ThinkPHP集成PayPal贝宝支付

一个项目需要用到paypal贝宝支付功能,第一次了解国外的api,真心蛋疼,搞了两天才弄明白,期间也找了很多资料,刚开始的时候迷迷糊糊,上官网看文档吧,全是英文,一点点用翻译工具翻译,翻到后面,都不知道翻译的是什么东西。

提交支付表单比较简单,重要的一步是跟paypal交互验证这点,搞明白了就木有其它问题了,刚开始不了解那个ipn的东西,所以绕了大大的一圈,悲催,脑子不好使。好了,不多说其它废话,先了解下什么是ipn吧:

什么是即时付款通知IPN
当您收到新的付款交易或者已发生的付款交易的状态发生变化时,PayPal都将异步(即不作为网站付款流程的一部分) 发送付款详细数据到您所指定的URL,以便您了解买家付款的具体情况并做出相应的响应。这个过程我们称作即时付款通知(简称 IPN)。示意图如下:

list-13

•  客户点击“付款”按钮向您的账户付款;
•  PayPal接受到客户的付款后,向您的服务器指定的URL通过POST方式发送IPN;
•  在您的服务器收到IPN之后,您必须将收到的POST信息对原样返回给PayPal进行验证,PayPal通过此方法帮您防

范欺骗或“中间人”攻击;(对IPN信息的验证过程我们称之为通知确认);
•  PayPal返回验证信息,通过验证为VERIFIED,不通过则为INVALD;
•  根据验证信息处理付款明细;
注:每次付款您可能收到多个IPN信息,一般来说直到收到IPN信息中的付款状态为Completed为止。

IPN数据包含了整个付款过程的详细信息,通过获取并分析它您可以:
•  自定义网站对客户购物进行实时回复:您可以以email或其他方式通知客户付款的状态;
•  自动履行相关操作:当收到IPN数据并确认付款状态已经完成后,您就可以立刻启动向买家发货的流程,也可以为买家进行虚拟货币的充值或者以某种方式将虚拟商品的卡号和密码发送给买家;
•  记录交易信息到您的数据库中;
….流程就是这样,这些都是官网上的,地址:

http://www.ebay.cn/public/paypal/integrationcenter/list__resource_2.html

表单提交的变量

http://www.ebay.cn/public/paypal/integrationcenter/list__resource_7.html

好了,就简单描述ipn到这里吧,下面直接上paypal类,最后还有paypal的一些参考手册的东西,也一并分享出来。

<?php
namespace Home\Controller;
use Home\Father;
header('Content-Type:text/html; charset=utf-8');
//Paypal贝宝支付
class PaypalController extends FatherController {
public function _empty(){
header("HTTP/1.0 404 Not Found");
$this->display('Common:404');
}
//提交表单
public function buildForm() {
$paypal_email = 'aaa@paypal.com';    //卖家账号
$order_sn = '12315456456';            //订单号
$custom = '12';                        //自定义额外参数
$currency_code = 'USD';                //货币类型
$charset = 'utf-8';                    //编码
$item_name = '订单名称';
$amount = 200;                        //金额
$formurl = 'https://www.sandbox.paypal.com/cgi-bin/webscr';//测试提交地址
//$formurl = 'https://www.paypal.com/cgi-bin/webscr';//正试提交地址
$weburl = 'http://'.$_SERVER['HTTP_HOST'].__APP__;
$notifyurl = $weburl.'/Paypal/notifyurl';            //IPN地址
$cancel_return = $weburl;                            //用户取消支付后返回的地址
$return = $weburl.'/Paypal/returnurl';                //支付成功后返回的地址
//更多表单变量,请访问paypal官网
//http://www.ebay.cn/public/paypal/integrationcenter/list__resource_7.html
$html = '<form id="paypalsubmit" action="'.$formurl.'" method="post">';
$html .= '<input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="charset" value="'.$charset.'"><input type="hidden" name="business" value="'.$paypal_email.'"><input type="hidden" name="receiver_email" value="'.$paypal_email.'"><input type="hidden" name="item_name" value="'.$item_name.'"><input type="hidden" name="item_number" value="'.$order_sn.'"><input type="hidden" name="currency_code" value="'.$currency_code.'"><input type="hidden" name="custom" value="'.$custom.'"><input type="hidden" name="amount" value="'.$amount.'"><input type="hidden" name="notify_url" value="'.$notifyurl.'" /><input type="hidden" name="cancel_return" value="'.$cancel_return.'" /><input type="hidden" name="return" value="'.$return.'" />';
$html .= '</form><script>document.forms["paypalsubmit"].submit();</script>';
echo $html;
}
/*IPN即时通知*/
public function notifyurl() {
//如果不是POST方式
if (!IS_POST) exit('非法请求');
//将POST变量记录在本地变量中
$data = array();
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$data[$key] = $value;
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
//将信息POST给paypal验证
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
//如果是测试的则用sandbox
$header .= "Host: www.sandbox.paypal.com\r\n";
//$header .= "Host: www.paypal.com\r\n";
$header .= "Content-Length: " . strlen($req) ."\r\n";
$header .= "Connection: close\r\n\r\n";
//在sandobx情况下,设置:
$fp = fsockopen('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
//$fp = fsockopen('ssl://www.paypal.com', 443, $errno, $errstr, 30);
//判断回复POST是否创建成功
if (!$fp) {
fclose($fp);
return false;
}else {
//将回复POST信息写入socket端口
fputs($fp, $header.$req);
//file_put_contents('data.txt', http_build_query($data), FILE_USE_INCLUDE_PATH);
//开始接受paypal对回复POST信息的认证信息
while(!feof($fp)) {
$res = fgets($fp, 1024);
//file_put_contents('aa.txt', $res, FILE_APPEND);
//已通过认证
if (strcmp($res, 'VERIFIED') == 0) {
//检查付款状态
//检查txn_id 是否已经是处理过
//检查receiver_email是否是您的paypal账户中的email地址
//检查付款金额和货币单位是否正确
//处理这次付款,更新订单状态
fclose($fp);
return false;
}else if (strcmp($res, 'INVALID') == 0) {
//echo 'ERROR';
//未通过认证,有可能是编码错误的或非法的POST信息
fclose($fp);
return false;
}
}
fclose($fp);
return false;
}
}
/*页面跳转处理方法
* 在贝宝支付完成后,进行跳转的地址
*/
public function returnurl() {
$tx = I('get.tx', '');                    //paypal交易号
$st = I('get.st', '');                    //支付状态
$amt = I('get.amt', '');                //付款金额
$cc = I('get.cc', '');                    //货币类型
$cm = I('get.cm', '');                    //额外自定义参数
$order_sn = I('get.item_number', '');    //订单号
//这里.....进行其它操作,你懂的.
}
}
?>

 

xia

分享到:
标签:paypal,paypal支付,贝宝,
^_^ 亲爱的客官,如果您觉得本文对您有好处,请移动你的鼠标点点下面的广告或上面的或右上角的,非常感谢~ ^_^

ThinkPHP集成PayPal贝宝支付:目前有8 条留言

  1. 感谢分享 祝您开心快乐每一天! 诚交友链 站务申请:www.3gwb.com

    2016-11-22 上午 3:43
  2. 2015-09-16 下午 3:53
  3. 过来支持一下 值得收藏分享

    2015-09-05 上午 5:35
  4. 4楼
    大米网:

    不错的 学习了

    2015-08-03 下午 9:32
  5. 地板
    小乐丫网:

    这个东西好呀

    2015-03-25 下午 7:05
  6. 官网上演示的不用登录也可以直接使用银行卡付款的呀

    2015-02-09 下午 4:11
  7. 我用了你的代码为什么每次在支付页面,不用paypal帐号付款,而是直接用银行卡支付,却要跳到提示需要登录paypal账户的登录页呢?

    2015-02-09 下午 3:37
    • paypal要登陆后才能付款的

      2015-02-09 下午 3:40