支付宝支付Java代码
支付宝调用流程
开发前的准备工作
配置应用网关
应用网关里面填写的值就是商户后台的异步回调地址.也就是在支付宝付完款之后,由支付宝调用商户,便于商户验证订单各信息和更新订单状态
授权回调地址
授权回调地址的值是指用户在使用支付宝付款成功后从支付宝跳转到商户自己的页面.
接口加密方式
这个用于商户的签名加密,有RSA2和RSA两种算法类型,默认是RSA2.开发人员可以使用支付宝提供的生成方式自己生成,然后将公钥上传到支付宝开放平台.这里提供支付宝生成密钥的教程和下载地址
现在提供一张的截图,显示配置的位置.到达方式:蚂蚁金服开放文档—> 右上角账户中的账号管理—>开发者中心—>我的应用(应用) —> 选择自己将要配置的应用名称点击右边的查看—>应用信息(就是截图看到的页面了)
支付宝支付流程:
前端调用商户后台支付接口
商户后台支付接口进行一些必要的业务逻辑上的处理之后调用支付宝的支付接口(原始支付API).需要的参数详见支付宝支付接口的参数说明.支付宝会返回一个form表单.商户后台支付接口将表单返回给前台.
前台将表单提交给支付宝,唤起支付宝客户端进行支付.
支付成功后支付宝会根据原始支付API中传入的异步通知地址notify_url,通过POST请求的方式将支付结果作为参数通知到商户后台系统.
商户后台系统在接到支付宝的异步通知后要在验证自己本身业务逻辑之外严格验证通知数据的正确性.
商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额)
校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
验证app_id是否为该商户本身
上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略.详情参见https://docs.open.alipay.com/203/105286/ 异步返回的验签
判断没有任何错误,打印success.否则支付宝服务器会不断重发通知,直至超过24小时22分钟.
开发需要准备的物料
pom.xml添加支付宝依赖
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.alipay</groupId>
<artifactId>alipay-sdk</artifactId>
<version>java20170307171631</version>
</dependency>
支付宝方面的参数
代码展示
商户后台支付接口
/**
* 支付宝支付
* @param req
* @param response
* @throws OperationFailedException
*/
@RequestMapping("alipay/Prepay")
@ResponseBody
public void aliPrepay(@RequestBody AliPrepayReq req, HttpServletResponse response) throws OperationFailedException {
Set<ConstraintViolation<AliPrepayReq>> constraintViolationSet = validator.validate(req);
if (constraintViolationSet.size() > 0) {
throw new OperationFailedException(constraintViolationSet.iterator().next().getMessage());
}
LibraOrder libraOrder = libraService.findLibraOrderByHashCode(req.getOutTradeNo());
Product product = productRepository.findOne(Long.valueOf(libraOrder.getProduct().getId()));
if(product == null) { throw new OperationFailedException("该商品不存在"); }
try{
String form = aliPayService.generateAliPay(req);
if(!"err".equals(form)){
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(form);// 直接将完整的表单html输出到页面
response.getWriter().flush();
}
}catch (Exception e){
throw new OperationFailedException("支付失败");
}
}
/**
* 支付宝方面订单号获取
* @param aliPrepayReq
* @return
* @throws OperationFailedException
*/
public String generateAliPay(AliPrepayReq aliPrepayReq) throws OperationFailedException {
AlipayClient alipayClient = new DefaultAlipayClient(aliPayUrl,
appId, rsaPrivateKey, "json", "UTF-8", rsaPublicKey, "RSA2"); //获得初始化的AlipayClient
Map<String, String> param = new HashMap<>();
AlipayTradeWapPayRequest alipay_request = new AlipayTradeWapPayRequest();
// 封装请求支付信息
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setOutTradeNo(aliPrepayReq.getOutTradeNo());
model.setSubject(aliPrepayReq.getSubject());
Integer totalAmount = aliPrepayReq.getTotalAmount();
model.setTotalAmount(String.valueOf(totalAmount / 100.0));
// model.setBody(aliPrepayReq.getBody());
model.setProductCode(aliPrepayReq.getProductCode());
alipay_request.setBizModel(model);
// 设置异步通知地址
alipay_request.setNotifyUrl(notifyUrl);
// 设置同步地址
alipay_request.setReturnUrl(returnUrl);
String form = "";
try {
LOGGER.info("alipay_request = "+jsonService.toJson(alipay_request));
// 调用SDK生成表单
form = alipayClient.pageExecute(alipay_request).getBody();
LOGGER.info("form = "+form);
} catch (Exception e) {
throw new OperationFailedException("支付出错");
}
return form;
}
异步回调接口
/**
* 支付宝方面异步回调
* @param request
* @return
* @throws OperationFailedException
*/
@RequestMapping("alipay/notifyCallback")
public String AlipayCallBack(HttpServletRequest request) throws OperationFailedException {
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
LOGGER.info("params = "+jsonService.toJson(params));
boolean verify_result = aliPayService.rsaCheck(params);
if(verify_result && aliPayService.dealWithAliPayChargeOrder(params)){
return "success";
}
return "false";
}
/**
* 订单验证
* @param params
* @return
*/
@Transactional
public boolean dealWithAliPayChargeOrder(Map<String, String> params) {
String outTradeNo = params.get("out_trade_no");
LibraOrder libraOrder = libraOrderRepository.findByHashCode(outTradeNo);
if (libraOrder == null) {
LOGGER.info("订单" + outTradeNo + "不存在");
return false;
}
boolean locked = distributeLocker.lock(USER_ALIPAY_DEAL_LOCK_KEY);
try {
if (locked) {
String totalAmount = params.get("total_amount");
double totalPrice = Double.parseDouble(totalAmount) * 100;
if(libraOrder.getTotalPrice() != Math.round(totalPrice)){
LOGGER.info("alipay和订单金额不一致");
return false;
}
if(totalPrice < 0 || libraOrder.getTotalPrice() < 0){
LOGGER.info("alipay或订单金额为负");
return false;
}
//set done
libraOrder.setPayAt(new Date());
libraOrder.setUpdateAt(new Date());
libraOrder.setStatus(ClientOrderStatus.PAYED);
//后台订单状态初始化为 等待接待
libraOrder.setServiceStatus(ServiceStatus.SERVICE_WAIT);
libraOrderRepository.save(libraOrder);
}
} finally {
if (locked) {
//TODO + order.getUserId()
distributeLocker.unlock(USER_ALIPAY_DEAL_LOCK_KEY);
}
}
return false;
}
/**
* 验证RSA签名
* @param params
* @return
* @throws OperationFailedException
*/
public boolean rsaCheck(Map<String, String> params) throws OperationFailedException {
try {
boolean verify_result = AlipaySignature.rsaCheckV1(params, rsaPublicKey, charset, signType);
LOGGER.info("verify_result = "+verify_result);
return verify_result;
} catch (AlipayApiException e) {
throw new OperationFailedException("验证签名失败");
}
}
---------------------
支付宝支付Java代码的更多相关文章
- (转载)Android支付宝支付封装代码
Android支付宝支付封装代码 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-12-22我要评论 这篇文章主要介绍了Android支付宝支付封装代码,Android支付的时候 ...
- app支付宝支付java服务端代码
app支付java服务端生成支付单文档 public String aliPay(String amount,Map<String,Object> body){ //实例化客户端 Alip ...
- 手把手教你完成App支付JAVA后台-支付宝支付JAVA
接着上一篇博客,我们暂时完成了手机端的部分支付代码,接下来,我们继续写后台的代码. 后台基本需要到以下几个参数,我都将他们写在了properties文件中: 支付宝参数 AliPay.payURL = ...
- 支付宝支付Java后台总结
这个支付的流程是前端H5(APP等)需要支付时调用后台的接口拿到我们加密的签名去调起支付宝的支付界面(支付宝APP)进行支付操作,并且前端在支付成功后,支付宝后台会回调一个我们在签名时写入的一个接口地 ...
- uni-app支付宝支付成功代码处理,获取trade_no数据
uni-app支付宝支付成功以后返回很多代码,我简单梳理一下,提出trade_no数据 uni.requestPayment({ provider: 'alipay', orderInfo: orde ...
- 微信支付与支付宝支付java开发注意事项
说明:这里只涉及到微信支付和淘宝支付 以官网的接口为准,主要关注[网关].[接口].[参数][加密方式][签名][回调] 第一步,了解自己的项目要集成的支付方式 常见的有扫码支付.网页支付.APP支付 ...
- MUI 支付宝支付接入
沙箱测试地址:https://openhome.alipay.com/platform/appDaily.htm 1资源下载地址:https://docs.open.alipay.com/54/106 ...
- 移动应用端的支付宝支付php开发流程
1.https://openhome.alipay.com/ 支付宝开放平台并创建应用,审核通过后并签约app支付拿到pid 2.按照官方文档用 [RSA签名验签工具.bat]生成应用公钥和私钥 3. ...
- spring_boot_pay支付宝,微信,银联支付详细代码案例
spring-boot-pay 支付服务:支付宝,微信,银联详细代码案例(除银联支付可以测试以外,支付宝和微信支付测试均需要企业认证,个人无法完成测试),项目启动前请仔细阅读 注意事项 . 友情提示 ...
随机推荐
- 20165205 2017-2018-2《Java程序设计》结对编程一 第二周总结
20165205 2017-2018-2<Java程序设计>结对编程一 第二周总结 设计思路 编写主类Arithmetic4 编写ArithmeticFunc类来实现计算,其中包括:加.减 ...
- PathUtil
public String getParentPath(final String originalPath) { boolean isSplitRequired = true; int lastSla ...
- nopcommerce 常用属性验证
Decimal可空:[UIHint("DecimalNullable")] datetime可空: [UIHint("DateTimeNullable")] i ...
- CentOS修改locale解决调用API乱码问题
查看所有的locale语言 locale 查看当前操作系统使用的语言 echo $LANG 永久设置系统locale语言 vi /etc/profile LANG="zh_CN.UTF-8& ...
- MyBatis与Hibernate的区别?
1.MyBatis学习成本低,Hibernate学习成本高: 2.MyBatis程序员编写SQL,Hibernate自动生成SQL:前者灵活及可优化高,后者不灵活及可优化低: 3.MyBatis适合需 ...
- python中 将你的名字转化成为二进制并输出
1 name = "吴彦祖" 2 for i in name: 3 i_by = bytes(i, encoding = "utf-8") 4 for i_bi ...
- django之setup()
#django包的__init__.py包含setup函数def setup(): """ Configure the settings (this happens as ...
- __file__ 作用以及模块导入方法
python 执行py 文件的时候,默认就会把当前目录增加到sys.path中 import os print(__file__) #打印文件当前的位置 直接在目录里面执行,结果显示当前文件(pych ...
- 使用STM32CubeMX生成RTC工程[秒中断]
现在我们在之前的工程(http://www.cnblogs.com/libra13179/p/7170791.html)中修改 /** ******************************** ...
- Spring cloud(2)B Eureka 注册微服务到服务中心
1.在provide上添加pom(必须加上web) 如果不加 启动后就会自己关闭 <dependency> <groupId>org.springframework.clo ...