Java支付宝支付(Alipay),支付接口,同步异步通知
做这个测试必须先注册成为支付宝开发者,最好要有一定的Java基础.注意同步异步通知这个必须要让支付宝可以访问你的项目,也就是说必须让支付宝可以访问你的项目中的方法,所以要把项目放在公网上,如果只是简单测试推荐使用花生壳
1.添加Alipay-sdk支付jar包:
alipay-sdk-java20170324180803.jar
alipay-sdk-java20170324180803-source.jar
commons-logging-1.1.1.jar //spring框架有日志包可忽略
2.编写支付宝网关密钥等配置文件
import java.io.FileWriter;
import java.io.IOException;
/* *
*类名:AlipayConfig
*功能:基础配置类
*详细:设置帐户有关信息及返回路径
*修改日期:2017-04-05
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
public class AlipayConfig {
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "20160926******";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "私钥";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "公钥";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://yan.eicp.net:26003/MyCSDN/pay/pay_notify";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://yan.eicp.net:26003/MyCSDN/pay/pay_return";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
// 支付宝网关
public static String log_path = "C:\\";
//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.编写支付宝支付工具类 :做的是将订单信息公钥私钥等交给支付宝进行加密后返回到界面层
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.it.exception.AlipayRuntimeException;
public class AlipayUtil {
public static String pay(String out_trade_no, String total_amount, String subject, String body) {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
//设置订单信息
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(out_trade_no);//必填,商户订单号
model.setSubject(subject);//必填,订单名称
model.setTotalAmount(total_amount);//必填,付款金额
model.setBody(body);//选填,商品描述
model.setProductCode("FAST_INSTANT_TRADE_PAY");//必填,电脑支付FAST_INSTANT_TRADE_PAY,手机支付QUICK_WAP_WAY
//model.setTimeoutExpress(timeout_express);//选填,增加自定义超时时间参数timeout_express
alipayRequest.setBizModel(model);
//请求
try {
//把支付信息加密好(私钥),向支付宝后端申请支付,后端用公钥解开信息,生成带有二维码的连接返回给用户,要求用户按链接跳转
String result = alipayClient.pageExecute(alipayRequest).getBody();
return result;
} catch (AlipayApiException e) {
throw new AlipayRuntimeException("支付宝支付失败", e);
}
}
}
4.编写控制器调用支付工具类
//发起支付,等待支付宝返回支付页面
@RequestMapping(value = "/paydo", method = RequestMethod.POST)
public void payDo(HttpServletRequest request, HttpServletResponse response,float money) throws Exception {
// System.out.println("测试支付");
Member m = (Member) request.getSession().getAttribute("m");
response.setContentType("text/html; charset=utf-8");//千万不要忘了设编码,否则密钥报错!!!!!!
PrintWriter out = response.getWriter(); //输出流
String out_trade_no = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + "_" + m.getId();//订单号
String total_amount = money + ""; //支付金额
String subject = m.getNickName() + "充值"; //订单名称
String body = "手机充值"; //商品描述
out.print(AlipayUtil.pay(out_trade_no, total_amount, subject, body));
}
//异步通知
@RequestMapping(value = "/pay_notify",method = RequestMethod.POST)
public void notifyUrl(HttpServletResponse response,HttpServletRequest request) throws IOException, AlipayApiException {
System.out.println("异步通知");
PrintWriter out = response.getWriter();
request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for(String str :requestParams.keySet()){
String name = str;
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名
if(!signVerified) {
System.out.println("验签失败");
out.print("fail");
return;
}
//商户订单号,之前生成的带用户ID的订单号
String out_trade_no = params.get("out_trade_no");
//支付宝交易号
String trade_no = params.get("trade_no");
//付款金额
String total_amount = params.get("total_amount");
//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");
if(trade_status.equals("TRADE_FINISHED")){
/*此处可自由发挥*/
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
//注意:
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
}else if (trade_status.equals("TRADE_SUCCESS")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序
//增加用户在数据库余额
String[] ss = out_trade_no.split("_");
int mid = Integer.parseInt(ss[1]);
Member m = memberService.findOne(mid);
m.setScore(m.getScore() + (int)Double.parseDouble(total_amount));
memberService.edit(m);
//添加充值记录
service.add(new PayInfo(trade_no,new Date(),"积分充值",m));
System.out.println("trade_no:"+trade_no+"<br/>out_trade_no:"+out_trade_no+"<br/>total_amount:"+total_amount);
}
out.print("success");
}
//同步通知
@RequestMapping(value = "/pay_return",method = RequestMethod.GET)
public String returnUrl(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
System.out.println("同步通知");
request.setCharacterEncoding("utf-8");//乱码解决,这段代码在出现乱码时使用
//获取支付宝GET过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for(String str :requestParams.keySet()){
String name = str;
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名
if(signVerified) {
System.out.println("验签成功-跳转到成功后页面");
//跳转至支付成功后的页面,
return "redirect:payment";
}else {
System.out.println("验签失败-跳转到充值页面让用户重新充值");
return "redirect:addmoney";
}
//打印请求中的字段
// for (String str:params.keySet()) {
// System.out.println(str +":"+ params.get(str));
// }
}
5.前端页面,调用controller方法即可
<form action="${pageContext.request.contextPath}/paydo" method="POST">
充值金额:<input type="text" name="money" />
<br/>
<input type="submit" value="充值"/>
</form>
Java支付宝支付(Alipay),支付接口,同步异步通知相关推荐
- java支付宝电脑网页支付
java支付宝电脑网页支付 官网文档:https://opendocs.alipay.com/open/270/105902 电脑网站支付 1.先给应用申请电脑网页支付功能 2.根据接口文档 ,请求支 ...
- PHP对接支付 alipay支付
踩过的坑 注意事项(以下接口参数针对的是沙箱环境): 1.支付结果返回客户端不需要htmlspecialchars php 不需要转义(对于php编译环境而言) 2.统一订单交易接口 :两个商户订单号 ...
- 服务器同步/异步通知参数说明 (支付宝)
开发平台文档 同步通知:支付宝sdk对商户的请求支付数据处理完成后,会将结果同步反馈给商户app端. 异步通知:对于App支付产生的交易,支付宝会根据原始支付API中传入的异步通知地址notify_u ...
- Java 支付宝手机网站支付下单 支付回调 及订单查询实现
首先,参考官方api: alipay.trade.wap.pay(手机网站支付接口2.0) 官方提供DEMO下载,不过是jsp的 准备工作:平台入驻,签约功能,应用上线,配置秘钥等 使用Alipay ...
- 支付宝手机网站支付开发记录之结果异步通知
开发的时候明明配置了异步通知,可是没有执行异步通知,就算是官方Demo也不行 https://openclub.alipay.com/read.php?tid=1314&fid=46& ...
- JAVA支付宝扫码支付开发流程
近期工作遇到支付宝扫码支付,经开发研究与3年前相比 API调用与配置更加简单方便,整体开发流程如下(后期会有对应的支付宝APP支付) 登录支付宝开发平台 -->开发接入 链接:https ...
- Java网络编程------IO模型的同步/异步/阻塞/非阻塞(1)
IO模型的同步/异步/阻塞/非阻塞 一.同步/异步/阻塞/非阻塞 1.同步和异步 2.阻塞和非阻塞 3.同步.异步和阻塞.非阻塞组合 二.IO 1.I/O 2.阻塞IO和非阻塞IO 3.同步IO和同步 ...
- Java支付宝沙箱环境支付,SDK接口远程调试【内网穿透】
文章目录 1.测试环境 2.本地配置 3. 内网穿透 3.1 下载安装cpolar内网穿透 3.2 创建隧道 4. 测试公网访问 5. 配置固定二级子域名 5.1 保留一个二级子域名 5.2 配置二级 ...
- java 支付宝h5网页支付接口,移动端h5网页调用支付宝支付接口
领导第一次让我做h5支付宝支付的时候,去了支付宝开放平台,一顿上上下下左左右右,看完了长呼一口气.这个支付好像没我啥事儿啊!小伙伴儿们自行查看:https://opendocs.alipay.com/ ...
最新文章
- 安装 ArcGISAPI31forSilverlight an i/o error occured while installing a file错误解决
- 深入理解java枚举_深入学习java枚举的应用
- Ant在Java项目中的使用(一眼就看会)
- android viewpager 详解,详解Android App中ViewPager使用PagerAdapter的方法
- Java 内存溢出(java.lang.OutOfMemoryError)解决
- 国产杀毒软件连续因“作弊”遭全球权威评测机构指责
- GNS3中下载路由器
- 国际电话号码的区号mysql数据表
- LeafLet实战-扩展工具栏指南
- 深信服技术认证之使用spark进行数据分析示例之拆分字段
- 大数据解决方案-最新全套文件
- 什么是虚拟计算机集群
- Android 炫酷动画APP,21 款炫酷动画开源框架,照亮你的APP
- 宇信易诚 两季度亏损与高管出走的背后
- python strftime 中文 年 月 日
- 【Python游戏】Python基于pygame实现的人机大战的斗兽棋小游戏 | 附源码
- FFmpeg再学习 -- 将 jpeg 转成 mp4
- Scala核心编程 第一章—Scala语言概述
- 难道这就是传说中的PR劫持吗?爱商网2ec.cn
- redis并发处理慢