贴一下支付核心代码,以供后续参考:

  • 业务层
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.aone.app.common.ali.pay.AlipayConfig;
import com.aone.app.service.AliAppPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import java.util.HashMap;
import java.util.Map; @Service
public class AliAppAppPayServiceImpl implements AliAppPayService { private static final Logger logger = LoggerFactory.getLogger("AliAppAppPayServiceImpl"); /**
* 预下单
* @param type
* @param out_trade_no
* @param money
* @return
*/
public Map<String, String> aliPay(String type,String out_trade_no,String money){ Map map=new HashMap();
map.put("code", "201");
map.put("msg", "解析失败");
map.put("orderString", ""); //实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL,AlipayConfig.APPID, AlipayConfig.PRIVATE_KEY,AlipayConfig.FORMAT,AlipayConfig.CHARSET,AlipayConfig.PUBLIC_KEY,AlipayConfig.SIGNTYPE); //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("支付");//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
model.setSubject("App支付宝支付");//商品的标题/交易标题/订单标题/订单关键字等
model.setOutTradeNo(out_trade_no);//商户网站唯一订单号
model.setTimeoutExpress("30m");//该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。
//注:若为空,则默认为15d。
model.setTotalAmount("0.01");//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
model.setProductCode("QUICK_MSECURITY_PAY");//销售产品码,商家和支付宝签约的产品码,为固定值 QUICK_MSECURITY_PAY
model.setPassbackParams(type); //公用参数(附加数据)
request.setBizModel(model);
request.setNotifyUrl(AlipayConfig.notify_url);
try {
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
//System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
//@TODO 返回支付所需参数
map.put("code", "200");
map.put("msg", "ok");
map.put("orderString", response.getBody());
return map;
} catch (AlipayApiException e) {
e.printStackTrace();
}
return map;
} /**
* 回调
* @param params
*/
public void notify(Map<String,String> params){
try {
//调用SDK验证签名
boolean flag= AlipaySignature.rsaCheckV1(params, AlipayConfig.PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);
logger.info("验签结果:{}", flag);
if(flag){
logger.info("支付状态为:{}", params.get("trade_status"));
//签名通过
if("TRADE_SUCCESS".equals(params.get("trade_status"))){//支付成功
//付款金额
String amount = params.get("buyer_pay_amount");
//商户订单号
String out_trade_no = params.get("out_trade_no");
//支付宝交易号
String trade_no = params.get("trade_no");
//公用参数(附加数据)
String passback_params = params.get("passback_params");
//@TODO 数据库操作 推送操作
if(StringUtils.isEmpty(passback_params)){
logger.info("附加数据类型为:{}", passback_params);
}else{
//@TODO 预支付下单后回调的逻辑 }
}
}
} catch (AlipayApiException e) {
logger.info("==================验签失败 !");
e.printStackTrace();
}
} }
  • 控制层回调接口
    /**
* 支付宝支付异步结果通知
* @param request
* @param response
*/
@RequestMapping(value = "aliPayNotify", method = {RequestMethod.GET, RequestMethod.POST})
public void aliPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
System.out.print("支付宝回调开始"+"\n");
//获取支付宝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] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//@TODO 业务(调用业务层的回调,那里面处理业务逻辑)
aliAppPayService.notify(params);
System.out.print("支付宝回调结束"+"\n");
}
  • 官方开发文档参考:https://docs.open.alipay.com/54/106370,如果代码有问题,参考官方文档。缺少其它东西参考支付宝手机网站支付
  • 开发过程中可能会出现:系统繁忙,请稍后再试。(ALIN10146),如果是这种错误的话,大概率配置的应用私钥和配置到蚂蚁金服上的应用公钥不匹配造成的,用RSA签名验签工具重新生成密钥后,使用工具上面的密钥匹配,成功后,再将应用公钥配置到平台上,重新拿新的支付宝公钥。

支付宝APP支付(基于Java实现支付宝APP支付)的更多相关文章

  1. 支付宝手机网站支付(基于Java实现支付宝手机网站支付)

    支付宝支付核心需要的参数是(APPID,PRIVATE_KEY,ALIPAY_PUBLIC_KEY) APPID:创建应用后就有的APPID. PRIVATE_KEY:应用私钥 ALIPAY_PUBL ...

  2. 微信APP支付(基于Java实现微信APP支付)

    步骤: 导入maven依赖 <!--微信支付--> <dependency> <groupId>com.github.wxpay</groupId> & ...

  3. 微信H5支付(基于Java实现微信H5支付)

    微信的H5支付区别与APP支付,主要在于预下单(返回的参数不一样),其它大体相同(基本没什么区别,区别在于有些人加密喜欢用MD5有些人喜欢用官方提供的加密方式加密,我用的是官方的),贴一下H5支付预下 ...

  4. wemall app中基于Java获取和保存图片的代码

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.分享其中关于 保存正在下载的图片URL集合和图片三种获 ...

  5. 手把手教你完成App支付JAVA后台-支付宝支付JAVA

    接着上一篇博客,我们暂时完成了手机端的部分支付代码,接下来,我们继续写后台的代码. 后台基本需要到以下几个参数,我都将他们写在了properties文件中: 支付宝参数 AliPay.payURL = ...

  6. app微信支付-java服务端接口 支付-查询-退款

    个人不怎么看得懂微信的文档,看了很多前辈的写法,终于调通了,在这里做一下记录. 首先来定义各种处理类(微信支付不需要特殊jar包,很多处理需要自己封装,当然也可以自己写完打个jar包) 参数要用jdo ...

  7. 基于IOS下的支付宝SDK的学习与使用——实现产品支付(二)

    首先本篇为作者原创,仅供学习使用,以后会不断完善,精炼.阅读之前请参考  上一篇 上一篇 中详细说明了结合官方支付宝SDK,对工程环境进行的一些配置,实现了支付,本篇重点说明一下,注意事项和原理,主要 ...

  8. pay-spring-boot 开箱即用的Java支付模块,整合支付宝支付、微信支付

    关于 使用本模块,可轻松实现支付宝支付.微信支付对接,从而专注于业务,无需关心第三方逻辑. 模块完全独立,无支付宝.微信SDK依赖. 基于Spring Boot. 依赖Redis. 我能做什么 支付宝 ...

  9. java实现支付宝电脑支付(servlet版本)

    前期准备: 蚂蚁金融开放平台 进行登录操作 进入我的开放平台 在上方找到沙箱,进入沙箱(网络编程虚拟执行环境). 这里的RSA2密钥设置下,我已经设置好了,所以便有了支付宝公钥(公钥是对外公开的,私钥 ...

随机推荐

  1. replicationController 使用

    [root@lab2 nginx-harbor]# cat http-test.yaml apiVersion: v1 kind: ReplicationController metadata: na ...

  2. API SendMessage 带参数

    代码未测试 [DllImport("USER32", EntryPoint = "SendMessage", CharSet = CharSet.Auto, S ...

  3. QT学习之usb摄像头采集(Opencv+QT)[cvCapture,IplImage,QImage]

    参考自:http://blog.chinaunix.net/uid-23381466-id-3826748.html 将Opencv中的cvCaptureFromCAM不断获得摄像头采集到的图像数据, ...

  4. 【GStreamer开发】GStreamer播放教程06——可视化音频

    目标 GStreamer有一系列把音频转换成视频的element.他们可以用于科学的目的或者增加音乐播放器的趣味性.本教程展示: 如何允许音频的可视化 如何选择可视化element 介绍 在playb ...

  5. Mysql sqlyog 错误1045

    首先打开运行窗口输入cmd进入DOS界面或者打开MySQL Workbench Step1: cd C:\Program Files\MySQL\MySQL Server 5.6\bin Step2: ...

  6. 方法重载overload与方法重写overwrite

    方法重载overload: 在同一个类中,出现相同的方法名,与返回值无关,参数列表不同:1参数的个数不同 2参数类型不同 在调用方法时,java虚拟机会通过参数列表来区分不同同名的方法 方法重写ove ...

  7. webpack to package typescript & scss

    Demo2操作手册 本Demo演示如何配合各种loader进行稍复杂的使用 准备环境 初始化环境, cd到demo目录之后, 执行如下命令: npm init -y npm install webpa ...

  8. Use Hexo to Build My Gitee Blog

      之前有自己建站托管自己的博客系统, 后来因为流量实在太少, 服务器又要每个月出钱, 然后就把她关了, 然是拥有自己的网站的心一直没有退去啊, 然后之前有接触到别人用GitHub托管静态网页的玩法, ...

  9. LeetCode 14. 最长公共前缀(Longest Common Prefix)

    14. 最长公共前缀 14. Longest Common Prefix 题目描述 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". Lee ...

  10. JAVA 后台面试之操作系统问题集锦

    1.进程和线程以及他们的区别 2.进程间通信的几种方式 3.线程同步的方式 4.死锁 5.分页和分段有什么区别?(内存管理) 6.操作系统中进程调度的策略有哪几种? 7.页面置换算法: 8.系统颠簸 ...