支付宝调用流程

开发前的准备工作

配置应用网关
应用网关里面填写的值就是商户后台的异步回调地址.也就是在支付宝付完款之后,由支付宝调用商户,便于商户验证订单各信息和更新订单状态
授权回调地址
授权回调地址的值是指用户在使用支付宝付款成功后从支付宝跳转到商户自己的页面.
接口加密方式
这个用于商户的签名加密,有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代码的更多相关文章

  1. (转载)Android支付宝支付封装代码

    Android支付宝支付封装代码 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-12-22我要评论 这篇文章主要介绍了Android支付宝支付封装代码,Android支付的时候 ...

  2. app支付宝支付java服务端代码

    app支付java服务端生成支付单文档 public String aliPay(String amount,Map<String,Object> body){ //实例化客户端 Alip ...

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

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

  4. 支付宝支付Java后台总结

    这个支付的流程是前端H5(APP等)需要支付时调用后台的接口拿到我们加密的签名去调起支付宝的支付界面(支付宝APP)进行支付操作,并且前端在支付成功后,支付宝后台会回调一个我们在签名时写入的一个接口地 ...

  5. uni-app支付宝支付成功代码处理,获取trade_no数据

    uni-app支付宝支付成功以后返回很多代码,我简单梳理一下,提出trade_no数据 uni.requestPayment({ provider: 'alipay', orderInfo: orde ...

  6. 微信支付与支付宝支付java开发注意事项

    说明:这里只涉及到微信支付和淘宝支付 以官网的接口为准,主要关注[网关].[接口].[参数][加密方式][签名][回调] 第一步,了解自己的项目要集成的支付方式 常见的有扫码支付.网页支付.APP支付 ...

  7. MUI 支付宝支付接入

    沙箱测试地址:https://openhome.alipay.com/platform/appDaily.htm 1资源下载地址:https://docs.open.alipay.com/54/106 ...

  8. 移动应用端的支付宝支付php开发流程

    1.https://openhome.alipay.com/ 支付宝开放平台并创建应用,审核通过后并签约app支付拿到pid 2.按照官方文档用 [RSA签名验签工具.bat]生成应用公钥和私钥 3. ...

  9. spring_boot_pay支付宝,微信,银联支付详细代码案例

    spring-boot-pay 支付服务:支付宝,微信,银联详细代码案例(除银联支付可以测试以外,支付宝和微信支付测试均需要企业认证,个人无法完成测试),项目启动前请仔细阅读 注意事项  . 友情提示 ...

随机推荐

  1. scrapy中 selenium(中间件) + 语言处理 +mysql

    在通过scrapy框架进行某些网站数据爬取的时候,往往会碰到页面动态数据加载的情况发生,如果直接使用scrapy对其url发请求,是绝对获取不到那部分动态加载出来的数据值.但是通过观察我们会发现,通过 ...

  2. python-对象方法、静态方法、类方法

    #-*- coding:utf-8 -*- #本次学习:对象方法.静态方法.类方法 class SeniorTestingEngineer: #属性--只能对象来调用self.salary work_ ...

  3. js 数组的crud操作

    增加push(); 向数组尾添加元素unshift(); 向数组头添加元素向数组指定下标添加元素:可以用Array提供的splice(); var arr = ['a','b','c']; arr.s ...

  4. day7--面向对象进阶(内含反射和item系列)

    一面向对象的结构和成员 1.1面向对象的结构 class A: company_name = '老男孩教育' # 静态变量(静态字段) __iphone = '1353333xxxx' # 私有静态变 ...

  5. Linux FACL(文件访问控制列表)

    文件有三种权限 属主权限   属组权限  其他权限 现在有这样一个场景,用户 A 想把文件共享给不是同组内用户 B ,而又不想修改其他权限,这时候 FACL 就起作用了 FACL可以给文件添加一个拓展 ...

  6. filter map reduce函数的使用

    #filter("处理逻辑","可迭代对象") 把可迭代对象依次处理逻辑处理,如果值为真就返回值,值为假就不返回; li = ['testA','yerA',' ...

  7. 【Source Insight 】之marco学习笔记1

    我们学习编程语言都是从Hello World!,现在我们学习marco也不例外 打开C:\Users\%USERPROFILE%\Documents\Source Insight 4.0\Projec ...

  8. RAD Tokyo 10.2.2

    TDialogService类 如果您是使用比较新的RAD Studio版本. 那么您应该开始改用FMX.DialogService程序单元中TDialogService类别的类别方法来取代以前的Me ...

  9. 微信小程序插件 - 开发教程

    昨天(2018.3.13),微信小程序发布了重大功能更新,支持插件的使用和开发,个人预计,不超过2个月,优质服务的插件将会如雨后春笋般涌现. 这篇文章,我将会带大家,从0开始,学习如何开发和使用插件. ...

  10. ABAP-计算器-动态表达式

    data:lv_value type string. call function 'EVAL_FORMULA' exporting formula = '90 <= 90' program = ...