thinkphp整合paypal贝宝支付,及post回调代码

一,先注册商业账号paypal官网www.paypal.com
二,接下来我们开始沙箱测试;当账户注册成功以后,paypal会分配给开发者账号两个沙箱测试账号(一个买家账号和一个商家账号)。

去paypal开发者账号管理端查看,登录地址:https://developer.paypal.com,用上面刚刚注册的账号密码即可,然后进入后台看到如下界面
在这里插入图片描述
我画红框的那两个账号就是paypal自动分配给我的,但是这个又是一个坑!!!!!我们可以看到Country的值为C2(代表中国区账号),但是我们千万不要同时拿着这两个账号来进行沙箱收付款测试,因为Paypal规定中国地区和中国地区的账户之间无法实现付款。把其中一个同账号修改为其它国家即可.

三,给你的商家测试账号是可以单独登录的.登录后,可以查看收款情况.里面的余额是虚拟的.登录地址为https://www.sandbox.paypal.com/,这里需要用上面红框中的商家账号登录
四.php代码

<?php
namespace Home\Controller;
use Think\Controller;
class PaypalController extends Controller {
	/** 
	* 自己的paypal账号 
	*/ 
	//private $account = 'info@ld.com';
private $account = 'sb-ylrml6894057@business.example.com';
	/** 
	* paypal支付网关地址 
	*/ 
	//private $gateway = 'https://www.paypal.com/cgi-bin/webscr?'; 
private $gateway = 'https://www.sandbox.paypal.com/cgi-bin/webscr?'; 
	public function order(){
		
		//print_r(I('get'));exit;
		$order_id=I('get.order_id');
		$price = I('get.price');
		// 初始化准备提交到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']		= $price; // 告诉Paypal,我要收多少钱 
		// 告诉Paypal,我要用什么货币。这里需要注意的是,由于汇率问题,
		// 如果网站提供了更改货币的功能,那么上面的amount也要做适当更改,
		// paypal是不会智能的根据汇率更改总额的 
		$pp_info['currency_code']	= 'USD';
		// 当用户成功付款后paypal会将用户自动引导到此页面。
		// 如果为空或不传递该参数,则不会跳转 
		//支付页面时,点击返回商家.也会返回这个地址
		$pp_info['return']		= 'http://www.asml.com/index.php?s=/home/index/user_order.html';	
		$pp_info['invoice']	= $order_id; 
		$pp_info['charset']	= 'utf-8'; 
		$pp_info['no_shipping']	= '2';
		$pp_info['shipping address']	= 'beijing'; 
		$pp_info['no_note']		= '1'; 
		// 当跳转到paypal付款页面时,用户又突然不想买了。则会跳转到此页面 
		$pp_info['cancel_return']	= 'http://www.asml.com/index.php?s=/home/index/user_order.html';	
		// Paypal会将指定 invoice 的订单的状态定时发送到此URL 
		// (Paypal的此操作,是paypal的服务器和我方商城的服务器点对点的通信,用户感觉不到)
		//post回调页面
		$pp_info['notify_url']	= 'http://www.asml.com/index.php?s=/home/paypal/notify/orderid/'.$order_id; 
		$pp_info['rm']	= '2'; 
		$pp_info['lc']	= 'en_US'; 
		$paypal_payment_url = $this->gateway.http_build_query($pp_info); 
		//echo "<a href='{$paypal_payment_url}'>Go Paypal!</a>"; 
		header("Location: {$paypal_payment_url}");
	}

	public function notify() {
		//本页面,可以测试时,单独访问,用来测试,订单号可以手动填好
		// 由于这个文件只有被Paypal的服务器访问,所以无需考虑做什么页面什么的,
		// 这个页面不是给人看的,是给机器看的 
		$order_id = floor( $_GET['orderid']); 
		//订单号,非法过滤,不要用int()过滤,否则超过10位的数字会显示不全
		$order_info = M('order')->where(array('code'=>$order_id))->find();
//print_r($order_info);exit;
$id=$order_info['id'];		
		// 由于该URL不仅仅只有Paypal的服务器能访问,其他任何服务器都可以向该方法发起请求。
		// 所以要判断请求发起的合法性,也就是要判断请求是否是paypal官方服务器发起的 
		// 拼凑 post 请求数据 
		$req = 'cmd=_notify-validate';// 验证请求 
		foreach ($_POST as $k=>$v){ 
			$v = urlencode(stripslashes($v)); 
			$req .= "&{$k}={$v}"; 
		} 
	//	$req="cmd=_notify-validate&mc_gross=10.00&invoice=1629876154398&protection_eligibility=Eligible&address_status=confirmed&payer_id=MS6Q4WXDA6VP8&address_street=1+Main+St&payment_date=00%3A22%3A51+Aug+25%2C+2021+PDT&payment_status=Completed&charset=gb2312&address_zip=95131&first_name=John&mc_fee=0.69&address_country_code=US&address_name=John+Doe&notify_version=3.9&custom=&payer_status=verified&business=sb-ylrml6894057%40business.example.com&address_country=United+States&address_city=San+Jose&quantity=1&verify_sign=AnHDRp16zRtu62B-gdTexFGNDtX8A01Yl0VBl4FxJtT7ephovzX7HUfB&payer_email=sb-epigs7127455%40personal.example.com&txn_id=0CR94435AC472235R&payment_type=instant&last_name=Doe&address_state=CA&receiver_email=sb-ylrml6894057%40business.example.com&payment_fee=0.69&shipping_discount=0.00&insurance_amount=0.00&receiver_id=EX2HU5HT9AUHC&txn_type=web_accept&item_name=%D6%A7%B8%B6%B6%A9%B5%A5%A3%BA1629876154398&discount=0.00&mc_currency=USD&item_number=&residence_country=US&test_ipn=1&shipping_method=Default&transaction_subject=&payment_gross=10.00&ipn_track_id=579f60def14a7";
	
	
//$cache2=RUNTIME_PATH.'2_'.rand().'.txt';
//file_put_contents($cache2,$req);//通过上面二行,可以打印出post给我们的数据.类似上面的参数$req

		
		$url_par=parse_url($this->gateway);
$fp = fsockopen($url_par[host],"80",$errnum,$errstr,30);
if(!$fp) {
return false;
} else {
fputs($fp, "POST ".$url_par[path]." HTTP/1.1\r\n");
fputs($fp, "Host: ".$url_par[host]."\r\n");
fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n");
fputs($fp, "Content-length: ".strlen($req)."\r\n");
fputs($fp, "Connection: close\r\n\r\n");
fputs($fp, $req . "\r\n\r\n");

// loop through the response from the server and append to variable

while(!feof($fp)) {
$this->validate_ipn_response .= fgets($fp, 1024);
}

fclose($fp); // close connection

}
if (eregi("VERIFIED",$this->validate_ipn_response)) {
	
	//$cache3=RUNTIME_PATH.'3_'.rand().'.txt';
	//	file_put_contents($cache3,$res);
				
				
	/** 
				* 判断订单的状态 
				* 判断订单的收款人 
				* 判断订单金额 
				* 判断货币类型 
				payment_status'] != 'Pending 证明这个款项正在审核,一般要一个星期左右,会自动到账,放心。
				*/ 

				if(($_POST['payment_status'] != 'Completed' && $_POST['payment_status'] != 'Pending') //Pending 证明这个款项付款成功,正在审核
				 OR ($_POST['receiver_email'] != $this->account)
				  OR ($_POST['mc_gross'] != $order_info['allprice'])
				   OR ('USD' != $_POST['mc_currency'])) { 
				// 如果有任意一项成立,则终止执行。由于是给机器看的,所以不用考虑什么页面。直接输出即可 
				
				//$cache3=RUNTIME_PATH.'fail_'.rand().'.txt';
			//	file_put_contents($cache3,1);//先用php生成缓存.
					echo 'fail';exit;
				} else {// 如果验证通过,则证明本次请求是合法的 
					$data['state']=2;//订单状态,2表示付款成功
					$orders=M('order_list')->where(array('oid'=>$id))->select();
	            	foreach($orders as $k=>$v){
	                	$product_id=$v['cid'];
	                	$oldkucun=M('contlist')->where(array('id'=>$product_id))->getField('kucun');
	                	$kucun=$oldkucun-$v['num'];
	                	//$data['kucun']=$kucun;//这里可以修改库存情况
	                	M('contlist')->where(array('id'=>$product_id))->save($data);
	            	}
					
			//	$cache3=RUNTIME_PATH.'success_1_'.rand().'.txt';
				//file_put_contents($cache3,1);//先用php生成缓存.
				
				
	            	M('order')->where(array('code'=>$_POST['invoice']))->save($data);
					echo 'success';exit;
				} 

} else {
echo 'fail';exit;

}
	} 

}
?>
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值