开发环境:springboot
最近一年两个项目开发,其中APP支付这块用到了微信支付,支付宝支付,以及转账到微信零钱,转账到支付宝账号等功能,下面会分成4个文章来介绍。
具体的开通微信和支付宝问题我不再叙述,直接上代码,代码会打包放在CSDN去下载,没有分的可以找我。
签约注意下支付宝和微信都要开通APP支付,支付宝开通单笔转账的支付宝账号,微信开通转账到零钱等
先从支付宝开始:
首先在pom.xml文件中添加支付宝SDK依赖
1支付宝参数配置类
/**
* 支付宝配置
*/
public class AliPayConfig {
//appid
public static String APP_ID_USER = "";
//应用私钥
public static String PRIVATE_KEY = "";
//应用公钥
public static String APP_PUBLIC_KEY = "";
//支付宝公钥
public static String ALI_PUBLIC_KEY ="";
//字符集
public static String CHARSET = "utf-8";
//URLs支付
public static String URL = "https://openapi.alipay.com/gateway.do";
//数据格式
public static String FORMAT = "json";
//加密方式
public static String SIGN_TYPE = "RSA2";
//接收支付宝回调地址notify_url //测试时候可以映射到本地地址可测试,不一定非要部署到线上
public static String NOTIFY_URL="可访问的线上地址;
//以下为支付宝授权登录所用
//授权服务对应的名称
public static String AUTH_API_NAME="com.alipay.account.auth";
//授权服务接口名称方法
public static String AUTH_API_METHOD="alipay.open.auth.sdk.code.get";
//授权app_name调用来源方的标识
public static String AUTH_APP_NAME="mc";
//调用业务的类型,常量值为
public static String AUTH_BIZ_TYPE="openservice";
// pid签约的支付宝账号对应的支付宝唯一用户号
public static String AUTH_PID="";
// 产品码
public static String AUTH_PRODUCT_ID="APP_FAST_LOGIN";
//授权范围
public static String AUTH_SCOPE="kuaijie";
// 标识授权类型,
public static String AUTH_TYPE="AUTHACCOUNT";
//
}
上面参数配置一定要区分好,尤其是应用公钥和支付宝公钥。
2支付宝工具类,DTO,等
import java.io.Serializable;
/**
* @Description: 订单表用dto
*/
public class OrderDto implements Serializable {
private static final long serialVersionUID = -27273789824211424L;
private Integer userId; //用户ID
private String orderNo; // 商户订单号,适配每个渠道对此参数的要求,必须在商户系统内唯一
private Float amount; // 订单总金额(必须大于0),单位为对应币种的最小货币单位,人民币为分
private String subject; // 商品标题,该参数最长为 32 个 Unicode 字符
private String body; // 商品描述信息,该参数最长为 128 个 Unicode 字符
private String description; // 订单附加说明,最多 255 个 Unicode 字符
private String wxZfbNum;//微信或支付宝支付成功微信支付宝生成的订单号
private String aliAuthCode;//支付宝auth_code
public Float getAmount() {
return amount;
}
public void setAmount(Float amount) {
this.amount = amount;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getWxZfbNum() {
return wxZfbNum;
}
public void setWxZfbNum(String wxZfbNum) {
this.wxZfbNum = wxZfbNum;
}
public String getAliAuthCode() {
return aliAuthCode;
}
public void setAliAuthCode(String aliAuthCode) {
this.aliAuthCode = aliAuthCode;
}
}
import java.io.Serializable;
import java.util.List;
public class ResultModel implements Serializable {
private static final long serialVersionUID = -2376100248939876442L;
private Integer status;//状态
private String message;//返回信息,成功或者失败信息
private String pkColumn;//生成主键的名称
private Integer pk;//插入操作时返回的主键
private Integer maxId;//最大查询返回id
private List
import java.util.Date;
/**
* 生成订单编号使用
*/
public class UUID {
private static Date date = new Date();
private static StringBuilder buf = new StringBuilder();
private static int seq = 0;
private static final int ROTATION = 99999;
public static synchronized long next() {
if (seq > ROTATION)
seq = 0;
buf.delete(0, buf.length());
date.setTime(System.currentTimeMillis());
String str = String.format("%1$tY%1$tm%1$td%1$tk%1$tM%1$tS%2$05d", date, seq++);
return Long.parseLong(str);
}
private UUID(){
}
}
3支付代码实现
app请求后台 和 支付宝支付成功通知
import com.alibaba.fastjson.JSONObject;
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.*;
import com.alipay.api.response.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
/**
* 支付宝订单支付
*/
@RestController
@RequestMapping("/pay/alipay")
public class AliPayController {
//@Autowired
// private IMicroAliPayService microAliPayService;
@PostMapping("aliPayOrder")
public ResultModel aliPayOrder(@RequestBody OrderDto dto, HttpServletRequest request,
HttpServletResponse response) {
ResultModel resultModel = new ResultModel();
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(AliPayConfig.URL, AliPayConfig.APP_ID_USER, AliPayConfig.PRIVATE_KEY, AliPayConfig.FORMAT,AliPayConfig.CHARSET ,AliPayConfig.ALI_PUBLIC_KEY, AliPayConfig.SIGN_TYPE);
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest aliRequest = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
String out_trade_no = String.valueOf(UUID.next());
model.setBody(dto.getBody());
model.setSubject(dto.getSubject());
model.setOutTradeNo(out_trade_no);
model.setTimeoutExpress("30m");
model.setTotalAmount(dto.getAmount()+"");//订单价格
model.setProductCode("QUICK_MSECURITY_PAY");
aliRequest.setBizModel(model);
aliRequest.setNotifyUrl(AliPayConfig.NOTIFY_URL);//3为充值订单
String orderStr = "";
try {
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse aliResponse = alipayClient.sdkExecute(aliRequest);
orderStr = aliResponse.getBody();//
//我是在这把支付订单信息做的保存,生成预支付订单,把orderStr传给APP进行处理并支付
resultModel.setStatus(1);
resultModel.setMessage("生成预支付订单成功");
resultModel.setResultObject(orderStr);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return resultModel;
}
}
/**
* 支付成功接收支付宝支付成功通知
*
* @param request
* @throws UnsupportedEncodingException,AlipayApiException
*/
@PostMapping("aliPayInquiryNotify")
public void aliPayNotify(HttpServletRequest request) throws UnsupportedEncodingException, AlipayApiException {
//获取支付宝POST过来反馈信息
Map params = new HashMap();
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] + ",";
}
if (name.equals("trade_status")) {
System.out.println("交易状态为:" + valueStr);
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
//切记alipaypublickey是支付宝的公钥,别错放应用公钥,如果再验签这出问题,先排查是否放错公钥,一般是这个问题造成
//boolean AlipaySignature.rsaCheckV1(Map params, String publicKey, String charset, String sign_type)
boolean flag = AlipaySignature.rsaCheckV1(params, AliPayConfig.ALI_PUBLIC_KEY, AliPayConfig.CHARSET, AliPayConfig.SIGN_TYPE);
//获取支付宝的通知返回参数
if (flag) {//验证成功
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
//客户订单编号
String auth_app_id = new String(request.getParameter("auth_app_id").getBytes("ISO-8859-1"), "UTF-8");
//买家登录支付宝id
String buyer_logon_id = new String(request.getParameter("buyer_logon_id").getBytes("ISO-8859-1"), "UTF-8");
//交易时间
String gmt_payment = new String(request.getParameter("gmt_payment").getBytes("ISO-8859-1"), "UTF-8");
//交易金额
String invoice_amount = new String(request.getParameter("invoice_amount").getBytes("ISO-8859-1"), "UTF-8");
//这里进行你的订单状态的更改,以及你的业务处理。处理完毕打印出success后,支付宝只会下发一次,否则会下发多次,可以查看文档理解下
System.out.println("success");
} else {//验证失败
//TODO service 生成订单支付失败历史记录
System.out.println("fail");
}
}