支付宝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这个文件
有密退款和无密退款的区别就是在一个方法上:
有密退款:
// 调用的接口名,无需修改
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的代码拷贝到你的项目中,再根据报错一步一步修改~
第三方的东西一遍都没做和做一遍是有很大的区别,然后做一遍和做一百遍就是一样的了!!!