支付宝支付之App支付

时间:2022-06-19 02:45:09

与微信支付对比,支付宝支付就没有那么多坑了,毕竟支付宝开放平台的文档还是描述的很详细的。

支付宝开放平台地址:https://docs.open.alipay.com/204/105297/

支付宝支付的流程如下图所示:

支付宝支付之App支付

项目中接入支付宝支付的步骤:

在这里分为了三个文件进行整理:

  1. 基础信息配置文件:AlipayConfig.java
  2. 调用API接口:AliPayUtil.java
  3. 对外接口:AlipayController.java

AlipayConfig.java

此文件中主要是配置了应用ID、支付宝公钥、应用密钥等基础信息,以及支付宝支付API提供的对外接口地址信息。

 package com.xhgx.web.pay.aliPay;

 import com.erenju.util.GlobleConfig;

 /**
* 支付宝支付基础信息配置
* @author rxn
* @date 2018/04/25
*/
public class AlipayConfig { /**
* 合作身份者ID,签约账号,16位纯数字
*/
public static String partner = "2088******";
/**
* 收款支付宝账号,一般情况下收款账号是签约账号
*/
public static String seller_id = partner;
/**
* appid
*/
public static String app_id = "2018*****";//正式
// public static String app_id = "2016*****";//沙箱
/**
* MD5密钥,32位字符串
*/
public static String key = "******";
/**
* 支付宝公钥 (使用工具生成)
*/
public static String public_key = "";//正式
/**
* 应用密钥 (特别长)
*/
public static String private_key = ""; /**
* 服务器异步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问
* 异步通知页面,就是接受支付宝支付结果返回信息的Contrller,可以处理自己的支付后的逻辑
*/
public static String notify_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/notify.json";
/**
* 服务器同步通知页面路径,需http://格式的完整路径,不能加自定义参数,必须外网可以正常访问
* 同步通知页面,就是支付宝支付成功后页面跳转的url
*/
public static String return_url = GlobleConfig.getProperty("PayNotifyUrl")+"/alipay/return.json";
/**
* 签名方式 ,(必须与生成密钥的签名方式一致)
*/
// public static String sign_type = "MD5";
public static String sign_type = "RSA2";
/**
* 日志文件
*/
public static String log_path = "";
/**
* 字符编码格式
*/
public static String charset = "utf-8";
/**
* 返回格式
*/
public static String format = "json";
/**
* 支付类型
*/
public static String payment_type = "1";
/**
* 支付宝网关(app支付接口)
*/
public static String AppPayUrl = "https://openapi.alipay.com/gateway.do";//线上
// public static String AppPayUrl = "https://openapi.alipaydev.com/gateway.do";//调试
}

AliPayUtil.java

此文件为工具类文件,实现了调用支付宝API提供的一些接口,下面的代码中主要包含了调用支付的接口和统一查询支付结果的接口。

 package com.xhgx.web.pay.aliPay;

 import java.net.URLEncoder;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.activiti.engine.repository.Model;
import org.springframework.security.web.header.writers.frameoptions.StaticAllowFromStrategy;
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.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse; /**
* 支付宝支付调用API接口
* @author rxn
* @date 2018/04/28
*
*/
public class AliPayUtil { /**
* 创建订单
* @param orderId 订单id
* @param total_amount 付款金额(单位:元)
* @return
* @throws AlipayApiException
*/
public static Map<String, Object> createOrder(String orderId,String total_amount) throws AlipayApiException{ String orderStr = "";
Map<String,Object> m = new HashMap<String, Object>();
try {
//封装订单
Map<String, String> orderMap = new LinkedHashMap<String,String>();
//公共参数
Map<String, String> bizModel = new LinkedHashMap<String,String>(); //商品参数封装
orderMap.put("out_trade_no",orderId);//商户订单号,必填
orderMap.put("subject", "*****");//订单名称,必填
// orderMap.put("total_amount", total_amount);//付款金额,必填
orderMap.put("total_amount", 0.01+"");//付款金额,必填
orderMap.put("body", "");//商品描述,选填
orderMap.put("timeout_express", "30m");//超时时间,选填
orderMap.put("prodect_code", "QUICK_MSECURITY_PAY");//销售产品码 //公共参数封装
bizModel.put("app_id", AlipayConfig.app_id);//appId
bizModel.put("method", AlipayConfig.AppPayUrl);//请求网关地址
bizModel.put("format", AlipayConfig.format);//返回格式
bizModel.put("private_key", AlipayConfig.private_key);//密钥 //实例化客户端,只需要实例化一次即可
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type);
//实例化具体API对应的request类,类名称和接口名称对应
AlipayTradeAppPayRequest ali_request = new AlipayTradeAppPayRequest(); //传入参数,sdk已经封装了公共参数,这里只需传入业务参数。
//以下方法是sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
// model.setPassbackParams(URLEncoder.encode(orderMap.get("body")));//公用回传参数,选填,UrlEncode之后才可以发送给支付宝。
model.setBody(orderMap.get("body"));//商品信息
model.setSubject(orderMap.get("subject"));//商品名称
model.setOutTradeNo(orderMap.get("out_trade_no"));//商品订单号
model.setTimeoutExpress(orderMap.get("timeout_express"));//交易超出时间
model.setTotalAmount(orderMap.get("total_amount"));//总金额
model.setProductCode(orderMap.get("prodect_code"));//销售产品码
model.setSellerId(AlipayConfig.seller_id);//支付宝用户id
ali_request.setBizModel(model);
ali_request.setNotifyUrl(AlipayConfig.notify_url);//回调地址 AlipayTradeAppPayResponse response = alipayClient.sdkExecute(ali_request);
orderStr = response.getBody(); if(response.isSuccess()){
m.put("result", orderStr);
m.put("code", 0);
m.put("msg", "订单生成成功");
}else{
m.put("code", 1);
m.put("msg", "订单生成失败");
} } catch (Exception e) {
// TODO: handle exception
m.put("code", 1);
e.printStackTrace();
m.put("msg", "订单生成失败");
} return m;
}
/**
* 查询订单
* @param orderId 订单id
* @return
* @throws AlipayApiException
*/
public static Map<String, Object> getOrder(String orderId) throws AlipayApiException{
System.out.println("查询支付结果");
Map<String,Object> m = new HashMap<String, Object>();
try {
//封装订单
Map<String, String> orderMap = new LinkedHashMap<String,String>();
//商品参数封装
orderMap.put("out_trade_no",orderId);//商户订单号,必填 //实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.AppPayUrl, AlipayConfig.app_id, AlipayConfig.private_key, "json", AlipayConfig.charset, AlipayConfig.public_key, AlipayConfig.sign_type);
//实例化具体API对应的request类,类名称和接口名称对应
AlipayTradeQueryRequest ali_request = new AlipayTradeQueryRequest(); //传入参数,sdk已经封装了公共参数,这里只需传入业务参数。
//以下方法是sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(orderMap.get("out_trade_no"));//商品订单号
ali_request.setBizModel(model);
ali_request.setNotifyUrl(AlipayConfig.notify_url);//回调地址 AlipayTradeQueryResponse response = alipayClient.execute(ali_request);
System.out.println(response.getCode()+"---"+response.getMsg());
if(response.isSuccess()){
System.out.println(response.getTradeStatus());
switch (response.getTradeStatus()) {
case "TRADE_FINISHED"://交易结束并不可退款
m.put("status", "OK");
break;
case "TRADE_SUCCESS"://交易支付成功
m.put("status", "OK");
break;
case "TRADE_CLOSED"://未付款交易超时关闭或支付完成后全额退款
m.put("status", "ERROR");
break;
case "WAIT_BUYER_PAY"://交易创建并等待买家付款
m.put("status", "ERROR");
break;
default:
m.put("status", "ERROR");
break;
} m.put("code", 0);
m.put("msg", "订单生成成功");
}else{
m.put("code", 1);
m.put("msg", "订单生成失败");
} } catch (Exception e) {
m.put("code", 1);
e.printStackTrace();
m.put("msg", "订单生成失败");
} return m;
}
}

AlipayController.java

此文件中主要是对外的异步通知接口,异步通知接口和同步通知接口性质是一样的,都是为了接收支付后平台返回的信息,下面的代码中只实现了异步通知接口。

 package com.xhgx.web.pay.aliPay;

 import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.xhgx.service.PayNotifyTblService;
import com.xhgx.service.domain.PayNotifyTbl;
import com.xhgx.web.SpringContextUtil;
import common.Logger; @Controller
public class AlipayController { public static Logger log = Logger.getLogger(AlipayController.class); /**
* 支付宝支付成功后,异步通知,回调该接口
* @param request
* @param response
* @return
*/
@ResponseBody
@RequestMapping("/alipay/notify.json")
public static String notifyUrl(HttpServletRequest request,HttpServletResponse response){
log.info("支付宝支付:"+"异步通知");
Map<String, String> params = new HashMap<String, String>(); //1.从支付宝回调的request中取值
Map<String, String[]> requestParams = request.getParameterMap(); for(Iterator<String> iter = requestParams.keySet().iterator();iter.hasNext();){
String name = iter.next();
String[] values = 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"), "gbk");
params.put(name, valueStr);
} //2.封装必须的参数
String out_trade_no = request.getParameter("out_trade_no");
String orderType = request.getParameter("body");
String tradeStatus = request.getParameter("trade_status");
String app_id = request.getParameter("app_id");
String trade_no = request.getParameter("trade_no");//支付宝交易号
String notify_time = request.getParameter("notify_time");//通知时间
String total_amount = request.getParameter("total_amount");//订单金额,单位元 //3.签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
boolean signVerified = false;
//3.1调用SDK验证签名
try {
signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.public_key, AlipayConfig.charset,AlipayConfig.sign_type);
} catch (AlipayApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} if(payNotifyTblService==null){
payNotifyTblService= (PayNotifyTblService) SpringContextUtil.getBean(PayNotifyTblService.class);
} //创建有一个对象,保存通知信息,根据业务需求来决定
PayNotifyTbl payNotifyTbl = new PayNotifyTbl();
payNotifyTbl.setPay_type(2);//支付类型:2支付宝
payNotifyTbl.setCreate_dt(new Date()); payNotifyTbl.setReturn_code(tradeStatus);
payNotifyTbl.setResult_code(tradeStatus); //4.对验签进行处理
if(signVerified){
if(tradeStatus.equals("TRADE_SUCCESS")){ //支付成功,进行业务处理 payNotifyTbl.setAppid(app_id);
payNotifyTbl.setOrder_id(out_trade_no);
payNotifyTbl.setTotal_fee(Double.parseDouble(total_amount));
payNotifyTbl.setTransaction_id(trade_no);
payNotifyTbl.setTime_end(notify_time);
payNotifyTbl.setPay_result("交易成功"); payNotifyTbl = payNotifyTblService.save(payNotifyTbl); return "success";
}else{
payNotifyTbl.setPay_result("参数有误");
payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
log.info("参数有误");
return "fail";
}
}else{
payNotifyTbl.setPay_result("交易失败");
payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
log.info("交易失败");
return "fail";
}
}else{
payNotifyTbl.setPay_result("验签失败");
payNotifyTbl = payNotifyTblService.save(payNotifyTbl);
log.info("验签失败");
return "fail";
}
} /**
* 支付宝支付成功后,同步通知
* @param request
* @param response
* @return
*/
@ResponseBody
@RequestMapping("/alipay/return.json")
public static String returnUrl(HttpServletRequest request,HttpServletResponse response){
log.info("支付宝支付:"+"同步通知"); return null;
}
}

开发中用到的工具包:https://files.cnblogs.com/files/ning0628/alipay-sdk-JAVA-3.0.0.zip;https://files.cnblogs.com/files/ning0628/alipaytradeapppay.zip

支付宝支付之App支付的更多相关文章

  1. 支付宝H5、APP支付服务端的区别(php)

    php支付宝H5和APP支付1.准备工作需要前往 蚂蚁金服开放平台申请https://openhome.alipay.com/developmentDocument.htm 2.大致流程1.用户添加商 ...

  2. asp&period;net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1

    2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...

  3. 微信支付(APP支付)-服务端开发(一)

    微信支付,首先需要注册一个商户平台公众账号,(网址:https://pay.weixin.qq.com/index.php/home/d_login) 目前微信支付的接入方式有四种方式:公众号支付,A ...

  4. 支付宝支付接口-app支付沙箱环境

    说明 开发阶段 需要验证自己的app支付加签是否正确,这里使用沙箱环境来进行模拟,使用ali的沙箱测试app和沙箱钱包app进行校验 准备阶段 1.进入沙箱页面 2.找到app支付文档 https:/ ...

  5. 微信支付之App支付

    项目接入微信支付的准备工作: 注册成为开发者,进行资质认证,这里是需要300元的审核费用的: 在微信商户平台创建应用,提交等待审核(大致需要5-7个工作日): 应用审核通过之后,进入应用,开通微信支付 ...

  6. uni-app - 支付(app支付、小程序支付、h5(微信端)支付)

    App支付.小程序支付.h5(微信端)支付 APP支付(内置) appPay.js /** * 5+App支付,仅支持支付宝以及微信支付 * * 支付宝Sdk集成,微信sdk未集成 * * @para ...

  7. php支付走过的坑(微信篇 包含h5支付和app支付 注册 秘钥 环境等等配置)

    支付这东西,说容易也容易,说难也难 代码这玩意还比较好说 但是 如果没有demo 直接去看官方文档 十有八九一脸懵逼 今天就整理一下 支付这块走过的坑 涉及 微信h5支付 支付宝h5支付 (api文档 ...

  8. asp&period;net core 微信APP支付(扫码支付,H5支付,公众号支付,app支付)之4

    微信app支付需要以下参数,类封装如下 public class WxPayModel { /// <summary> /// 应用ID /// </summary> publ ...

  9. php 微信支付V3 APP支付

    前言:微信支付现在分为v2版和v3版,2014年9月10号之前申请的为v2版,之后申请的为v3版.V3版的微信支付没有paySignKey参数. php 微信支付类 <?php class We ...

随机推荐

  1. TortoiseGit 连接oschina不用每次输入用户名和密码的方法

    每次git clone 和push 都要输入用户名和密码.虽然安全,但在本机上每次都输有些麻烦,如何记住用户名和密码呢? 在网上看了各种方法,太杂,很多可能环境不一样,一直行不通.最后找到一种有效的方 ...

  2. 【代码笔记】iOS-对iphone手机进行判断的一些函数

    代码: #import "RootViewController.h" //为判断手机的型号 -(NSString*)deviceString添加头文件 #import " ...

  3. CMPP3&period;0实现物联网卡通讯

    当下物联网发展迅猛,物联网卡可以接受短信指令,实现千里之外尽可掌控.本人做过一个这类项目,把相关经验记录下来,分享给需要的人. 物联网卡通讯其实跟电话卡一样,可以使用CMPP协议.不过由于物联网卡位数 ...

  4. Socket通信客户端设计(Java)

    public class Client extends JFrame implements Runnable{ private JPanel jPanel= new JPanel(); private ...

  5. Java Web 前端高性能优化(二)

    一.上文回顾 上回我们主要从图片的合并.压缩等方面介绍前端性能优化问题(详见Java Web 前端高性能优化(一)) 本次我们主要从图像BASE64 编码.GZIP压缩.懒加载与预加载以及 OneAP ...

  6. Silverlight CheckBoxList

    项目要用到复选框,可是在Silverlight中不存在CheckBoxList.通过查阅资料以及依据自己的理解,写了简单演示样例: 1.XAML <UserControl x:Class=&qu ...

  7. Python3 多线程编程(thread、threading模块&rpar;

    threading是对thread的封装. 1.开启线程: t=threading.Thread(target=sayhi,args=('hh',)) t.start() 或者先建一个Thread的继 ...

  8. Docker切换国内镜像

    本人是Ubuntu系统 Ubuntu 18.04 安装 Docker-ce 1.更换国内软件源,推荐中国科技大学的源,稳定速度快(可选) sudo cp /etc/apt/sources.list / ...

  9. sql 删除默认索引,对象 依赖于 列,由于一个或多个对象访问此列

    declare @name varchar(50)select  @name =b.name from sysobjects b join syscolumns aon b.id = a.cdefau ...

  10. 遇到Io阻塞时会切换任务之【爬虫版】

    #! /usr/bin/env python3 # -*- coding:utf- -*- from urllib import request import gevent,time from gev ...