随着互联网和移动互联网发展,越来越多的企业和个人开发者在自己的网站接入支付接口,但是网上从接口级详细介绍的很少,完整成功的案例代码几乎没有。

本文经过对米扑代理接入支付宝接口的实战,成功解决了付款/退款的基本逻辑,并且还解决了自动发货/退货等支付逻辑。

先看成功接入支付宝接口付款/退款,自动发货/退货的网站实例:

米扑代理: http://proxy.mimvp.com/price.php

 

支付宝开放平台开发文档

即时到帐技术集成文档 (推荐

支付历史接口 (参考)

支付API目录 (参考)

服务端SDK (参考)

 

代码文件结构

create_direct_pay_by_user-php-UTF-8
  │
  ├lib┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈类文件夹
  │  │
  │  ├alipay_core.function.php ┈┈┈┈┈┈支付宝接口公用函数文件
  │  │
  │  ├alipay_notify.class.php┈┈┈┈┈┈┈支付宝通知处理类文件
  │  │
  │  ├alipay_submit.class.php┈┈┈┈┈┈┈支付宝各接口请求提交类文件
  │  │
  │  └alipay_md5.function.php┈┈┈┈┈┈┈支付宝接口MD5函数文件
  │
  ├log.txt┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈日志文件
  │
  ├alipay.config.php┈┈┈┈┈┈┈┈┈┈┈┈基础配置类文件
  │
  ├alipayapi.php┈┈┈┈┈┈┈┈┈┈┈┈┈┈支付宝接口入口文件
  │
  ├notify_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈服务器异步通知页面文件
  │
  ├return_url.php ┈┈┈┈┈┈┈┈┈┈┈┈┈页面跳转同步通知文件
  │
  ├cacert.pem ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈用于CURL中校验SSL的CA证书文件
  │
  └readme.txt ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈使用说明文本

alipay-account-rates-to-pay-the-refund-process-01

 

支付宝交易状态自定义

// 支付宝【即时支付】交易状态 (user_order)
$ALIPAY_INSTANT_TRADE_STATUS_ARRAY = array(	"0"=>"NO_PAY",
											"1"=>"WAIT_BUYER_PAY",
											"4"=>"TRADE_FINISHED",
											"5"=>"TRADE_CLOSED",
											"7"=>"TRADE_PENDING",
											"8"=>"TRADE_SUCCESS",
											"WAIT_BUYER_PAY"=>"1",
											"TRADE_FINISHED"=>"4",
											"TRADE_CLOSED"=>"5",
											"TRADE_PENDING"=>"7",
											"TRADE_SUCCESS"=>"8",
											"0_desc"=>"买家未付款",
											"1_desc"=>"等待买家付款",
											"4_desc"=>"交易成功结束",
											"5_desc"=>"交易中途关闭(已结束,未成功完成)",
											"7_desc"=>"等待卖家收款",
											"8_desc"=>"交易成功(可退款)");


// 支付宝【即时支付】退款状态
$ALIPAY_INSTANT_REFUND_STATUS_ARRAY = array("0"=>"NO_REFUND",
											"5"=>"REFUND_SUCCESS",
											"6"=>"REFUND_CLOSED",
											"REFUND_SUCCESS"=>"5",
											"REFUND_CLOSED"=>"6",
											"0_desc"=>"未申请退款",
											"5_desc"=>"退款成功",
											"6_desc"=>"退款关闭");

 

支付宝的付款/退款状态

//计算得出通知验证结果
$alipayNotify = new AlipayNotify($alipay_config);
$verify_result = $alipayNotify->verifyNotify();

if($verify_result) {//验证成功
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//请在这里加上商户的业务逻辑程序代
	
	//——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
    //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表
	$out_trade_no = $_POST['out_trade_no'];			// 商户订单号
	$trade_no = $_POST['trade_no'];					// 支付宝交易号
	$trade_status = $_POST['trade_status'];			// 交易状态
	
	$trade_status_id = $ALIPAY_INSTANT_TRADE_STATUS_ARRAY[$trade_status];
	$paid_dtime = $_POST['gmt_payment'];		// 该笔交易的买家付款时间(POST notify通知时间)
// 	$paid_dtime = $_POST['notify_time'];		// 该笔交易的买家付款时间(GET  return通知时间)


	@$seller_email = $_POST['seller_email'];
	@$seller_id = $_POST['seller_id'];
	@$seller_actions = $_POST['seller_actions'];			// ========== 无 ==========
	@$buyer_email = $_POST['buyer_email'];
	@$buyer_id = $_POST['buyer_id'];
	@$buyer_actions = $_POST['buyer_actions'];				// ========== 无 ==========
	

	@$receive_name = $_POST['receive_name'];				// ========== 无 ==========
	@$receive_address = $_POST['receive_address'];			// ========== 无 ==========
	@$receive_zip = $_POST['receive_zip'];					// ========== 无 ==========
	@$receive_phone = $_POST['receive_phone'];				// ========== 无 ==========
	@$receive_mobile = $_POST['receive_mobile'];			// ========== 无 ==========
	

	@$notify_dtime = $_POST['notify_time'];
	@$refund_status = $_POST['refund_status'];
	@$refund_status_id = $ALIPAY_INSTANT_REFUND_STATUS_ARRAY[$refund_status];
	@$refund_dtime = $_POST['gmt_refund'];	// 交易退款时间
	
	


	if( $trade_status == 'WAIT_BUYER_PAY' ){
		// 等待买家付款
		 
		$order_status = 0;	// 已下单,等待买家付款
		$sql = sprintf( "update user_order
    					 set trade_no='%s', status=%d, trade_status=%d, refund_status=%d, refund_dtime='%s', notify_dtime='%s',
    						 seller_email='%s', seller_id='%s', seller_actions='%s', buyer_email='%s', buyer_id='%s', buyer_actions='%s',
						 where is_send_goods = 0 and id = '%s'; ",
				$trade_no, $order_status, $trade_status_id, $refund_status_id, $refund_dtime, $notify_dtime,
				$seller_email, $seller_id, $seller_actions, $buyer_email, $buyer_id, $buyer_actions,
				$out_trade_no );
		$result = sql_insert( 'mimvp_proxy', $sql );
		if ( $result == 1 )
		{
			write_success_session($out_trade_no);
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}
	}
	else if( $trade_status == 'TRADE_SUCCESS' && $refund_status == "" ) {
		// 买家已付款,等待卖家发货,自动填写发货信息
	
		$order_status = 8;
		$sql = sprintf( "update user_order
		    					 set trade_no='%s', status=%d, trade_status=%d, refund_status=%d, refund_dtime='%s', notify_dtime='%s',
		    						 seller_email='%s', seller_id='%s', seller_actions='%s', buyer_email='%s', buyer_id='%s', buyer_actions='%s',
		    						 receive_name='%s', receive_address='%s', receive_zip='%s', receive_phone='%s', receive_mobile='%s', paid_dtime='%s'
								 where is_send_goods = 0 and id = '%s'; ",
				$trade_no, $order_status, $trade_status_id, $refund_status_id, $refund_dtime, $notify_dtime,
				$seller_email, $seller_id, $seller_actions, $buyer_email, $buyer_id, $buyer_actions,
				$receive_name, $receive_address, $receive_zip, $receive_phone, $receive_mobile, $paid_dtime,
				$out_trade_no );
		$result = sql_insert( 'mimvp_proxy', $sql );
		if ( $result == 1 )
		{
			write_success_session($out_trade_no);
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}

		is_trade_success($out_trade_no);
   		echo $sHtml;
	}
	else if( $trade_status == 'TRADE_FINISHED' && $refund_status == "" ) {
	//判断该笔订单是否在商户网站中已经做过处理
		//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
		//如果有做过处理,不执行商户的业务程序
	
		$order_status = 4;
		$order_confirm_dtime = date('Y-m-d H:i:s');
		$order_finish_dtime = date('Y-m-d H:i:s');
		$sql = sprintf( "update user_order set status=%d, trade_status=%d, seller_actions='%s', buyer_actions='%s', confirm_dtime='%s', finish_dtime='%s', notify_dtime='%s', is_finish = 1 where is_send_goods = 1 and id = '%s'; ",
				$order_status, $trade_status_id, $seller_actions, $buyer_actions, $order_confirm_dtime, $order_finish_dtime, $notify_dtime, $out_trade_no );
					$result = sql_insert( 'mimvp_proxy', $sql );
		if ( $result == 1 )
		{
			write_success_session($out_trade_no);
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}
	}
	else if( $trade_status == 'TRADE_CLOSED' && $refund_status == "" ){
		// 交易中途关闭(已结束,未成功完成)
				 
		$order_status = 32;
		$order_finish_dtime = date('Y-m-d H:i:s');
		$sql = sprintf( "update user_order set status=%d, trade_status=%d, seller_actions='%s', buyer_actions='%s', finish_dtime='%s', notify_dtime='%s', is_finish = 1 where is_send_goods = 1 and id = '%s'; ",
						$order_status, $trade_status_id, $seller_actions, $buyer_actions, $order_finish_dtime, $notify_dtime, $out_trade_no );
							$result = sql_insert( 'mimvp_proxy', $sql );
							if ( $result == 1 )
		{
			write_success_session($out_trade_no);
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}
	}
	
	
	if( $trade_status == 'TRADE_CLOSED' && $refund_status == "REFUND_SUCCESS" ){
		// 交易中途关闭(已结束,未成功完成)
	
		$order_status = 105;
		$refund_finish_dtime = date('Y-m-d H:i:s');
		$sql = sprintf( "update user_order set status=%d, trade_status=%d, refund_status=%d, refund_dtime='%s', refund_finish_dtime='%s', seller_actions='%s', buyer_actions='%s', notify_dtime='%s', is_finish = 1 where id = '%s'; ",
							$order_status, $trade_status_id, $refund_status_id, $refund_dtime, $refund_finish_dtime, $seller_actions, $buyer_actions, $notify_dtime, $out_trade_no );

		$refund_return_success_status = is_refund_return_success($out_trade_no, $buyer_actions, $seller_actions, $trade_status_id, $refund_status_id);
		$result = sql_insert( 'mimvp_proxy', $sql );
		
		if ( $result == 1 && $refund_return_success_status == 1 )
		{
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}
	}
	else if( $refund_status == 'REFUND_CLOSED' /* && $trade_status == 'TRADE_FINISHED' */ ) {
		# 退款关闭, 买卖双方终止了退款操作,并走正常交易流程完成了交易(卖家拒绝退款,买家确认收货,交易完成)

		$order_status = 106;
		$refund_finish_dtime = date('Y-m-d H:i:s');
		$sql = sprintf( "update user_order set status=%d, trade_status=%d, refund_status=%d, refund_finish_dtime='%s', seller_actions='%s', buyer_actions='%s', notify_dtime='%s', is_finish = 1 where id = '%s'; ",
							$order_status, $trade_status_id, $refund_status_id, $refund_finish_dtime, $seller_actions, $buyer_actions, $notify_dtime, $out_trade_no );

		$result = sql_insert( 'mimvp_proxy', $sql );
		if ( $result == 1 )
		{
			echo "success";		// 成功插入数据库,返回通知支付宝不要再发送异步通知
		}
	}
	
	
//     if($_POST['trade_status'] == 'TRADE_FINISHED') {
// 		//判断该笔订单是否在商户网站中已经做过处理
// 			//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 			//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 			//如果有做过处理,不执行商户的业务程序
				
// 		//注意:
// 		//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知

//         //调试用,写文本函数记录程序运行情况是否正常
//         //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
//     }
//     else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
// 		//判断该笔订单是否在商户网站中已经做过处理
// 			//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 			//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
// 			//如果有做过处理,不执行商户的业务程序
				
// 		//注意:
// 		//付款完成后,支付宝系统发送该交易状态通知

//         //调试用,写文本函数记录程序运行情况是否正常
//         //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
//     }

// 	//——请根据您的业务逻辑来编写程序(以上代码仅作参考)——
        
// 	echo "success";		//请不要修改或删除
	
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
else {
    //验证失败
    echo "验证失败" . "<br>";
    echo "verify_result : " . $verify_result . "<br>";

    //调试用,写文本函数记录程序运行情况是否正常
    //logResult("这里写入想要调试的代码变量值,或其他运行的结果记录");
}

 

成功案例

本文是我成功接入支付宝到米扑代理后,并实现了自动发货,自动退货的过程中,遇到的问题,解决的办法,希望对大家有帮助。

米扑代理成功案例:

http://proxy.mimvp.com/price.php

 

a)订单状态

alipay-payment-refunds-01

 

b)交易成功订单

alipay-payment-refunds-02

 

c)退款成功订单

alipay-payment-refunds-03

 

 

参考推荐:

支付宝接口付款/退款详细逻辑流程

支付宝、财付通、网银、快钱接口的收费费率 (推荐)

支付宝接口付款/退款详细逻辑流程

支付宝php支付接口说明

支付宝在线支付接口申请教程

支付宝服务合同

支付宝即时到账