之所以转载这篇文章,不是因为他实现了多少代码,而是说文章中会有一些遇到的问题和解决方法。
前一段时间也做了alipay和tenpay的接口编码,其实说白了这些东西都差不多。只是因为这篇文章中说的是https接口,会有点不太一样。
alipay和tenpay最终都是跳转到对方的网站上做进一步的支付的,paypal可能不太一样(没仔细折腾过,所以才要转这篇)
上原文:http://shiningray.cn/paypal-ipn.html
最近终于搞定了该死的Paypal ipn,特地在此留下点东西备忘。
所谓paypal ipn(Instant Payment Notification),就是Paypal开发的一种能主动通知第三方卖家系统交易状态的一种机制。IPN的原理很简单,就是当产生了一个交易之后, 交易状态发生变化时,如用户已经付款、或者退款、撤销时,Paypal利用常用的HTTP POST方式,将交易的一些变量提交给网站的某个页面(称之为IPN Handler),当这个页面接受到请求时候,将这些数据原封不动加上一个指示验证的cmd=_notify-validate
,POST回Paypal的接口地址,如果数据正确,那么Paypal返回字符串VERIFIED,否则为INVALID,如果结果为VERIFIED,那么你的程序就可以使用这些数据进行操作。
但代码的调试是一件很痛苦的事情,因为作为第三方开发人员,不可能开两个帐号,每次测试还要之间交易一些钱,所以Paypal专门开发了Sandbox给开发人员进行开发,首先到https://developer.paypal.com/ 注册一个开发帐号,好了之后再进入Sandbox建立测试用的Paypal虚拟帐号(至少应该建立一个Business的和一个Personal的),这 种账号注册方法和Paypal的流程一样,信息可以是假的,包括银行帐号、信用卡(其实Paypal Sandbox会自动生成一些随机的号码)。接下来需要激活Paypal Sandbox的虚拟帐号,注意,这里不管你在Paypal Sanbox注册时填什么邮件地址,有任何发送到虚拟帐号所填邮箱的邮件都存会在开发帐号的管理界面中的Email页(导航栏上有)中。登录 Sandbox的虚拟Paypal环境,还需要验证虚拟帐号的银行,这里可以随便填,然后通过Add Funds来给账户充值(想填多少填多少)。然后,还需要激活IPN的选项,在Business的那个账户的Profile设置页面中,点击,然后点击 Edit按钮,打开IPN,这里如果你使用的是固定的IPN Handle,可以直接将地址填入。
接下来,我们测试的时候,应该将Paypal接口的地址设置为https://www.sandbox.paypal.com/cgi-bin/webscr
最后基本的流程为:
- 用户在我们的网站上选择商品、放入购物车,然后检查准备支付
- 网站根据购物车中的商品,生成Paypal的支付表单(也是提交到上面IPN用的Paypal接口地址),包含了此次交易的一些信息(下次会专门找机会解释一下)。并在自己的数据库中生成一张订单记录。
- Paypal在Session中记录下这些交易信息
- 用户用Paypal账户登录Paypal(Sandbox用Sandbox的虚拟帐号),复查明细,点击Pay按钮
- Paypal进行交易处理,如果我们的Paypal收款帐号在接受帐款上没有什么问题(没有特别的需要在界面上“Accept”的地方),交易完成,那么Paypal会发送一个IPN,并发送提示邮件。
- 我们IPN Handler接受到信息,首先向Paypal进行校验,如果信息正确,然后根据信息和自己数据库中进行比对,如果无误,可以将支付信息保存,并修改订单状态。
- 然后Paypal会显示一个界面表示交易完成,此时如果用户点击“Return”按钮,Paypal会将用户送回我们网站指定地点。
- 我们网站迎接用户回来,向用户表示感谢,并进行提醒,给出订单号等等。
整个流程基本如下,不过其中有很多要注意的地方:
- 我们看到了,接口地址是https开头的,也就是要求使用SSL进行连接, 其实Paypal Sandbox可以使用http,但是最后实际的Paypal接口,不支持http协议,所以如果你用PHP写IPN Handler脚本的话,在验证信息的代码部分,如果简简单单使用fopen、HTTP_Request之类的工具是没用的,PHP的socks库不支持SSL,应该使用curl,有两种方法,一个是使用PHP扩展中的libcurl,Paypal官方发布的SDK中便是使用的这个方法,但Paypal的SDK非常复杂,如果想自己写,可以使用Snoopy,一个简单实用的PHP请求库(它自己说是模拟了浏览器的行为),而它使用的是Curl的可执行文件,通过管道获得结果,而非php的libcurl,所以自己cURL的主页上下载一个支持SSL的编译版本,可能还需要安装OpenSSL,不过对于Linux系统,可能应该会都带。
- 在支付表单中,可以自己设置
notify_url
字段,来指定此次交易的信息应该发送到哪个地方,这样就可以覆盖在Profile中我们的设置,另外,这个字段要进行urlencode
。
- 我们得到的IPN信息中,
status
对应的便是交易状态,如Complete
表示完成,首字母大写,而验证结果则是VERIFIEY
或者INVALID
,全部大写,具体的内容,可以查看Paypal官方的文档订单管理整合指南。
--EOF--
文章虽老,但值得参考一下。
我不知道是我的PHPDOC版本有问题还是有我的netbeans版本有问题,反正,我在netbeans里调 用生成phpdoc没有成功
但是我在命令行下,以及WEB管理界面,我都成功生成了。
OK说一下我的步骤
1、下载phpdocumentor并解压到某个目录
2、修改phpdoc.bat,把set PHPCli的路径改成我的PHP实际路径
3、在命令行下运行phpdoc,会提示你选择哪一个INI文件,选择0.即使用默认的phpdocumentor.ini
4、然后运行。。phpdoc -d xxx -t xxx就over了。
这是最简单的方法
然后是进入WEB管理,这时候,要把phpdocument解压到WEB可访问的目录下,打开http://localhost/xxx/phpdoc.php会跳转到builder目录下
然后设置一下directoy目录和Target目录。同时也可以选择生成的格式,最后选择create,就直接创建成功了。。
然而我在官方的介绍下(视频)我却没有配置成功。。。不知道怎么回事,想知道官方是怎么下载的,可以到官方看一下视频。。。地址是:http://netbeans.org/kb/docs/php/screencast-phpdoc.html
如果觉得我说的简单,这里有一份比较详细的介绍:
这里还有一篇操作步骤的:
http://xieye.iteye.com/blog/229131
- phpDocumentor有两种正式的安装方法。
- (以下都翻译自pear.php.net的文档, -- xieye --)
-
- 第一种方式是从pear.php.net 或 sourceforge.net下载压缩包并解压。另一种方式是通过pear安装
-
- 注意:以下假定用户使用PHP5,window系统!
-
- 第一种方法:
- 下载后,如果希望使用命令行接口,解压到任意路径(假设在C:\Program Files\),
- 修改C:\Program Files\PhpDocumentor-1.4.2\phpdoc.bat
- 把第一行修改SET phpCli=C:\usr\local\php\cli\php.exe
- 令等号右边的值为php.exe的路径
- 我的机器是SET phpCli=D:\php5\php.exe
-
- 在命令行输入C:\Program Files\PhpDocumentor-1.4.2\phpdoc,其实是一个批处理文件
- 会出现一个dos界面,给你选择ini文件。
- 后面就不知道了。
-
-
- 如果想使用web接口,你必须先把apache和php装好,把PhpDocumentor-1.4.2这个文件夹
- 拷贝到文档根目录下,然后在浏览器url栏输入:
- http://localhost/PhpDocumentor-1.4.2/phpdoc.php
- 然后浏览器会自动跳转,选择index.html,后面的操作就很简单了。
-
-
-
-
-
- 第二种方法:通过pear安装
- 进入dos的php目录
- 输入pear install -a PhpDocumentor
-
- 如果想使用web接口,则必须首先改变一个配置,
- pear config-set data_dir /path/to/document_root/pear
- 最后的路径应该是/php文档根路径/pear
- (也可以在web接口中改变这个值)
-
- 我没在第二种方法的web接口试验成功。
-
-
- 如果使用web接口的话,还有选择,
- 一种是每次都选择输入文件,输出文件之类。
- 另一种是使用一个配置文件,里面把什么都定义好,
- 进入页面后,先选择这个配置文件,然后点击“创建”按钮,
最近,明显是空了很多,于是我看了一下以前的代码,再看看网上那些开源的代码,拿来与我自己曾经写的代码进行验证这样可以了解别人的优点。知道自己的缺点在哪里。
1、xweibo,这个玩意目前很流行,腾讯也出了个iweibo,反正说白了,如果你是用接口,那无非就那么点东西。根据接口拉拉数据,你也不用关系他们的数据结构和其他的代码等。当然如果你要整合到你自己的系统里就不是这么简单啦。所以,我在看xweibo是怎么个折腾法。。。。所幸,你看xweibo的index.php文件里,被注释了很多代码那就是xweibo的一些常用方法,看看就差不多了。。。
2、sablog for Yii前台基本完成,目前已经完成:文章列表、回复列表、标签云、标签云对应文章列表,首页,侧边栏也基本完成。待完成的有:友情链接页,文章内容页,高级搜索页,搜索结果页等(文章内容页里的东西最多,有考虑象以前想过的,本博客历史上的今天,关联文章,回复,等等,太多了。。当然还要考虑预留点广告位,方便自己塞广告。文章内容,也还得考虑那些程序的语法标签,附件,缩略图。。。。唉)
通过设置,现在的Url规则也尽量与原来一致,这样我如果切换的话,几乎就可以平移了。。
把官方这段贴上来,http://www.yiiframework.com/doc/guide/1.1/zh_cn/topics.url。。。不是照抄就能用的,得看清楚一些符号。。黑黑
我们使用一些例子来解释网址工作规则。我们假设我们的规则包括如下三个:
array(
'posts'=>'post/list',
'post/<id:\d+>'=>'post/read',
'post/<year:\d{4}>/<title>'=>'post/read',
)
-
调用$this->createUrl('post/list')
生成/index.php/posts
。第一个规则适用。
-
调用$this->createUrl('post/read',array('id'=>100))
生成/index.php/post/100
。第二个规则适用。
-
调用$this->createUrl('post/read',array('year'=>2008,'title'=>'a sample post'))
生成/index.php/post/2008/a%20sample%20post
。第三个规则适用。
-
调用$this->createUrl('post/read')
产生/index.php/post/read
。请注意,没有规则适用。
总之,当使用createUrl生成网址,路线和传递给该方法的GET参数被用来决定哪些网址规则适用。如果关联规则中的每个参数可以在GET参数找到的,将被传递给createUrl ,如果路线的规则也匹配路线参数,规则将用来生成网址。
这是一篇来自Yii官方的文章,写在了1.1.6的new fetures里面,值得一看,最起码,你在看完后,下次被人面试的时候,问到什么 是MVC,你可以有回答的东西了。
不多说,上原文,内容也不复杂,所以我就不翻译了(其实是我翻译不来,将就着看看可以,可是要翻译成人人都能看得懂的内容就难了)。。。
原文来自于:http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices,目前官方也确实没有中文版。
Although Model-View-Controller (MVC) is known by nearly every Web developer, how to properly use MVC in real application development still eludes many people. The central idea behind MVC is code reusability and separation of concerns. In this section, we describe some general guidelines on how to better follow MVC when developing a Yii application.
To better explain these guidelines, we assume a Web application consists of several sub-applications, such as
- front end: a public-facing website for normal end users;
- back end: a website that exposes administrative functionality for managing the application. This is usually restricted to administrative staff;
- console: an application consisting of console commands to be run in a terminal window or as scheduled jobs to support the whole application;
- Web API: providing interfaces to third parties for integrating with the application.
The sub-applications may be implemented in terms of modules, or as a Yii application that shares some code with other sub-applications.
1. Model
Models represent the underlying data structure of a Web application. Models are often shared among different sub-applications of a Web application. For example, a LoginForm
model may be used by both the front end and the back end of an application; a News
model may be used by the console commands, Web APIs, and the front/back end of an application. Therefore, models
-
should contain properties to represent specific data;
-
should contain business logic (e.g. validation rules) to ensure the represented data fulfills the design requirement;
-
may contain code for manipulating data. For example, a SearchForm
model, besides representing the search input data, may contain a search
method to implement the actual search.
Sometimes, following the last rule above may make a model very fat, containing too much code in a single class. It may also make the model hard to maintain if the code it contains serves different purposes. For example, a News
model may contain a method named getLatestNews
which is only used by the front end; it may also contain a method named getDeletedNews
which is only used by the back end. This may be fine for an application of small to medium size. For large applications, the following strategy may be used to make models more maintainable:
-
Define a NewsBase
model class which only contains code shared by different sub-applications (e.g. front end, back end);
-
In each sub-application, define a News
model by extending from NewsBase
. Place all of the code that is specific to the sub-application in this News
model.
So, if we were to employ this strategy in our above example, we would add a News
model in the front end application that contains only the getLatestNews
method, and we would add another News
model in the back end application, which contains only the getDeletedNews
method.
In general, models should not contain logic that deals directly with end users. More specifically, models
-
should not use $_GET
, $_POST
, or other similar variables that are directly tied to the end-user request. Remember that a model may be used by a totally different sub-application (e.g. unit test, Web API) that may not use these variables to represent user requests. These variables pertaining to the user request should be handled by the Controller.
-
should avoid embedding HTML or other presentational code. Because presentational code varies according to end user requirements (e.g. front end and back end may show the detail of a news in completely different formats), it is better taken care of by views.
2. View
Views are responsible for presenting models in the format that end users desire. In general, views
-
should mainly contain presentational code, such as HTML, and simple PHP code to traverse, format and render data;
-
should avoid containing code that performs explicit DB queries. Such code is better placed in models.
-
should avoid direct access to $_GET
, $_POST
, or other similar variables that represent the end user request. This is the controller's job. The view should be focused on the display and layout of the data provided to it by the controller and/or model, but not attempting to access request variables or the database directly.
-
may access properties and methods of controllers and models directly. However, this should be done only for the purpose of presentation.
Views can be reused in different ways:
-
Layout: common presentational areas (e.g. page header, footer) can be put in a layout view.
-
Partial views: use partial views (views that are not decorated by layouts) to reuse fragments of presentational code. For example, we use _form.php
partial view to render the model input form that is used in both model creation and updating pages.
-
Widgets: if a lot of logic is needed to present a partial view, the partial view can be turned into a widget whose class file is the best place to contain this logic. For widgets that generate a lot of HTML markup, it is best to use view files specific to the widget to contain the markup.
-
Helper classes: in views we often need some code snippets to do tiny tasks such as formatting data or generating HTML tags. Rather than placing this code directly into the view files, a better approach is to place all of these code snippets in a view helper class. Then, just use the helper class in your view files. Yii provides an example of this approach. Yii has a powerful CHtml helper class that can produce commonly used HTML code. Helper classes may be put in an autoloadable directory so that they can be used without explicit class inclusion.
3. Controller
Controllers are the glue that binds models, views and other components together into a runnable application. Controllers are responsible for dealing directly with end user requests. Therefore, controllers
-
may access $_GET
, $_POST
and other PHP variables that represent user requests;
-
may create model instances and manage their life cycles. For example, in a typical model update action, the controller may first create the model instance; then populate the model with the user input from $_POST
; after saving the model successfully, the controller may redirect the user browser to the model detail page. Note that the actual implementation of saving a model should be located in the model instead of the controller.
-
should avoid containing embedded SQL statements, which are better kept in models.
-
should avoid containing any HTML or any other presentational markup. This is better kept in views.
In a well-designed MVC application, controllers are often very thin, containing probably only a few dozen lines of code; while models are very fat, containing most of the code responsible for representing and manipulating the data. This is because the data structure and business logic represented by models is typically very specific to the particular application, and needs to be heavily customized to meet the specific application requirements; while controller logic often follows a similar pattern across applications and therefore may well be simplified by the underlying framework or the base classes.