一个项目需要用到paypal贝宝支付功能,第一次了解国外的api,真心蛋疼,搞了两天才弄明白,期间也找了很多资料,刚开始的时候迷迷糊糊,上官网看文档吧,全是英文,一点点用翻译工具翻译,翻到后面,都不知道翻译的是什么东西。
提交支付表单比较简单,重要的一步是跟paypal交互验证这点,搞明白了就木有其它问题了,刚开始不了解那个ipn的东西,所以绕了大大的一圈,悲催,脑子不好使。好了,不多说其它废话,先了解下什么是ipn吧:
什么是即时付款通知IPN
当您收到新的付款交易或者已发生的付款交易的状态发生变化时,PayPal都将异步(即不作为网站付款流程的一部分) 发送付款详细数据到您所指定的URL,以便您了解买家付款的具体情况并做出相应的响应。这个过程我们称作即时付款通知(简称 IPN)。示意图如下:
• 客户点击“付款”按钮向您的账户付款;
• 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的一些参考手册的东西,也一并分享出来
display('Common:404'); } //提交表单 public function buildForm() { $paypal_email = '[email protected]' ; //卖家账号 $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 = ''; 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.0rn"; $header .= "Content-Type: application/x-www-form-urlencodedrn"; //如果是测试的则用sandbox $header .= "Host: www.sandbox.paypal.comrn "; //$header .= "Host: www.paypal.comrn "; $header .= "Content-Length: " . strlen($req) ."rn"; $header .= "Connection: closernrn"; //在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', ''); //订单号 //这里.....进行其它操作,你懂的. } } ?>