java支付宝无密退款

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xb12369/article/details/51644061

支付宝API提供了两处退款的接口文档:

①统一收单退款接口:https://doc.open.alipay.com/doc2/apiDetail.htm?spm=a219a.7395905.0.0.0ej0mo&docType=4&apiId=759

②及时到账有密退款接口:https://doc.open.alipay.com/doc2/detail?treeId=66&articleId=103571&docType=1


两者的区别的是:如果你是alipay.trade.pay那么就该调统一收单的退款接口①

像我们是App端支付mobile.securitypay.pay,然后我直接调统一收单的接口,一直提示

{"is_success":"F","error":"BATCH_NO_FORMAT_ERROR"}

那么这个时候,可以像支付宝的技术客服咨询了~你把情况说下,他就会发个rar的包给你,这里面有各种版本的退款源码,照着葫芦画瓢,相关参数改成自己的就可以直接用了~~

关键的代码参考:alipayapi.jsp这个文件

有密退款和无密退款的区别就是在一个方法上:

有密退款:

扫描二维码关注公众号,回复: 3422949 查看本文章

// 调用的接口名,无需修改
	public static String service = "refund_fastpay_by_platform_pwd";


无密退款:(你先得申请,通过了才可以使用,客服说需要3-5个工作日,其实一天就差不多了)

sParaTemp.put("service", "refund_fastpay_by_platform_nopwd");


解接下来就是借花献佛了:

配置文件:

package com.alipay.config;

/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *版本:3.3
 *日期:2012-08-10
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
	
 *提示:如何获取安全校验码和合作身份者ID
 *1.用您的签约支付宝账号登录支付宝网站(www.alipay.com)
 *2.点击“商家服务”(https://b.alipay.com/order/myOrder.htm)
 *3.点击“查询合作者身份(PID)”、“查询安全校验码(Key)”

 *安全校验码查看时,输入支付密码后,页面呈灰色的现象,怎么办?
 *解决方法:
 *1、检查浏览器配置,不让浏览器做弹框屏蔽设置
 *2、更换浏览器或电脑,重新登录查询。
 */

public class AlipayConfig {
	
	//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
	// 合作身份者ID,以2088开头由16位纯数字组成的字符串
	public static String partner = "";
	// 商户的私钥
	public static String key = "";

	//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
	

	// 调试用,创建TXT日志文件夹路径
	public static String log_path = "D:\\";

	// 字符编码格式 目前支持 gbk 或 utf-8
	public static String input_charset = "utf-8";
	
	// 签名方式 不需修改
	public static String sign_type = "MD5";

}

说明: 这里有个坑,key退款这里是长度为32位的key,不是私钥,源代码上写的是私钥,你说坑爹不坑爹,哈哈,调试半天哪里都没有错,发现就是一直失败!!!

关于查看MD5退款key的位置:


没有安装数字证书,我懒得找我boss要验证码,就指路到这里吧~~


开始退款:

<%
/* *
 *功能:即时到账批量退款无密接口接入页
 *版本:3.3
 *日期:2012-08-14
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。

 *************************注意*****************
 *如果您在接口集成过程中遇到问题,可以按照下面的途径来解决
 *1、商户服务中心(https://b.alipay.com/support/helperApply.htm?action=consultationApply),提交申请集成协助,我们会有专业的技术工程师主动联系您协助解决
 *2、商户帮助中心(http://help.alipay.com/support/232511-16307/0-16307.htm?sh=Y&info_type=9)
 *3、支付宝论坛(http://club.alipay.com/read-htm-tid-8681712.html)
 *如果不想使用扩展功能请把扩展功能参数赋空值。
 **********************************************
 */
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.alipay.config.*"%>
<%@ page import="com.alipay.util.*"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.util.Map"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>支付宝即时到账批量退款无密接口</title>
	</head>
	<%
		////////////////////////////////////请求参数//////////////////////////////////////

		//服务器异步通知页面路径
		String notify_url = "http://商户网关地址/refund_fastpay_by_platform_nopwd-JAVA-UTF-8/notify_url.jsp";
		//需http://格式的完整路径,不允许加?id=123这类自定义参数

		//退款批次号
		String batch_no = new String(request.getParameter("WIDbatch_no").getBytes("ISO-8859-1"),"UTF-8");
		//必填,每进行一次即时到账批量退款,都需要提供一个批次号,必须保证唯一性

		//退款请求时间
		String refund_date = new String(request.getParameter("WIDrefund_date").getBytes("ISO-8859-1"),"UTF-8");
		//必填,格式为:yyyy-MM-dd hh:mm:ss

		//退款总笔数
		String batch_num = new String(request.getParameter("WIDbatch_num").getBytes("ISO-8859-1"),"UTF-8");
		//必填,即参数detail_data的值中,“#”字符出现的数量加1,最大支持1000笔(即“#”字符出现的最大数量999个)

		//单笔数据集
		String detail_data = new String(request.getParameter("WIDdetail_data").getBytes("ISO-8859-1"),"UTF-8");
		//必填,格式详见“4.3 单笔数据集参数说明”
		
		
		//////////////////////////////////////////////////////////////////////////////////
		
		//把请求参数打包成数组
		Map<String, String> sParaTemp = new HashMap<String, String>();
		sParaTemp.put("service", "refund_fastpay_by_platform_nopwd");
        sParaTemp.put("partner", AlipayConfig.partner);
        sParaTemp.put("_input_charset", AlipayConfig.input_charset);
		sParaTemp.put("notify_url", notify_url);
		sParaTemp.put("batch_no", batch_no);
		sParaTemp.put("refund_date", refund_date);
		sParaTemp.put("batch_num", batch_num);
		sParaTemp.put("detail_data", detail_data);
		
		//建立请求
		String sHtmlText = AlipaySubmit.buildRequest("", "", sParaTemp);
		out.println(sHtmlText);
	%>
	<body>
	</body>
</html>

说明: 这里的参数detail_data,他说详情请见【必填,格式详见“4.3 单笔数据集参数说明”】,找了一圈也没发现在哪里,然后我就猜:

找了统一退款那里的biz_content的参数,我以为是Json格式的,然后照着json往支付宝传参数,结果又报错了~我勒个暴脾气!!!!!

一问客服他说是参数与参数直接用^【shift+6】连接,即:

String detail_data = outCode+"^"+applyReturn.getMoney()+"^"+applyReturn.getReason();

开始调用:

//支付宝
						SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

						if(trans.getListSplitTrans()!=null&&trans.getListSplitTrans().size()>0){
							Item item = this.itemService.findItemById(applyReturn.getItemId());

							if(item!=null){
								//这里是下单后并未直接支付,而是后面拆单后一个一个地支付
								for (SplitTrans split : trans.getListSplitTrans()) {
									if(split.getSellerId().equals(item.getUserId())){
										if(split.getPm()==applyReturn.getPm()){
											outCode = split.getOutCode();
											finalPay = split.getFinalpay().intValue();
										}else{
											result = "提现中的支付方式跟交易流水中的支付方式不一致!!";
										}
										break;
									}
								}
							}else{
								result = "退款中的商品不存在~";
							}
						}else if(!StringUtils.isEmpty(trans.getOutCode())){
							if(trans.getPm()==applyReturn.getPm()){
								outCode = trans.getOutCode();
								finalPay = trans.getFinalpay().intValue();

							}else{
								result = "提现中的支付方式跟交易流水中的支付方式不一致!!";
							}
						}

						//把请求参数打包成数组
						String timestamp = df.format(new Date());
						String batch_no = CommonUtil.formatDateyyyymmddhhmmssSSS(new Date());
						
						Map<String, String> sParaTemp = new HashMap<String, String>();
						sParaTemp.put("service", "refund_fastpay_by_platform_nopwd");
						sParaTemp.put("partner", AliPay.partner);
						sParaTemp.put("_input_charset", AliPay.charset);
						sParaTemp.put("notify_url", AliPay.notify_url);
						sParaTemp.put("batch_no",batch_no);//退款批次号:回调的时候根据此字段修改退款申请的状态
						sParaTemp.put("refund_date", timestamp);//退款请求时间
						sParaTemp.put("batch_num", "1");//退款总笔数
						
						String detail_data = outCode+"^"+applyReturn.getMoney()+"^"+applyReturn.getReason();
						sParaTemp.put("detail_data", detail_data);//单笔数据集
						
						map = new HashMap<String, Object>();
						map.put("omark", omark);
						map.put("lastCt", new Date());
						map.put("batch_no", batch_no);
						//1:申请退款中(sta=5);2:已经处理成功(sta=6);3:卖家发货(sta=2);6:平台不通过(sta=7);
						this.applyService.modifyApplyReturn(id, map);

						//建立请求
						String sHtmlText = AlipaySubmit.buildRequest("", "", sParaTemp);
						System.out.println(sHtmlText);

						//为了保证支付宝回调先改变申请和订单的状态,这里线程休眠5s
						Thread.sleep(5000);
						break;

说明: 支付宝退款需要回调修改退款申请的状态,我担心它不及时,搞的休眠5s再说,哈哈~【ps:微信退款就直接退掉了】




这里我的心得是:

刚拿到支付宝的源码的时候,我一头雾水,擦,我还是做后端的呢,提供API(接口)是我的强项,我都给整蒙了,那很多其他的人我相信也是一样的~


第一步:

先把支付宝提供的源码放在Myeclipse中,这样有很多的参数就可以直接点击过去查看,便于快速查阅~


第二步:

修改相关参数成自己的,到时候放在自己的项目的时候,文件夹名字可得以都不用改了~


第三步:

一般jsp页面是它的入口,把jsp的代码拷贝到你的项目中,再根据报错一步一步修改~



第三方的东西一遍都没做和做一遍是有很大的区别,然后做一遍和做一百遍就是一样的了!!!



猜你喜欢

转载自blog.csdn.net/xb12369/article/details/51644061