沙箱环境
1:先去蚂蚁金服入驻
得到开发需要的信息 appid 支付宝网管 商户私钥和支付宝公钥
2:配置参数类
pom引入jar包
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
配置支付宝需要的参数配置
package com.fandemi.utils.alipay;
public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "appid";
// 支付宝网关
public static String url = "https://openapi.alipaydev.com/gateway.do";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String private_key = "";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String public_key = "";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "";
// 签名方式
public static String sign_type = "RSA2";// 签名方式
public static String format = "json";//参数格式为json
// 字符编码格式
public static String charset = "utf-8";
}
3:配置参数实体类
package com.fandemi.utils.alipay;
public class AlipayBean {
/**
* 商户订单号,必填
*
*/
private String out_trade_no;
/**
* 订单名称,必填
*/
private String subject;
/**
* 付款金额,必填
* 根据支付宝接口协议,必须使用下划线
*/
private String total_amount;
/**
* 商品描述,可空
*/
private String body;
/**
* 超时时间参数
*/
private String timeout_express= "10m";
/**
* 产品编号
*/
private String product_code= "FAST_INSTANT_TRADE_PAY";
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTotal_amount() {
return total_amount;
}
public void setTotal_amount(String total_amount) {
this.total_amount = total_amount;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTimeout_express() {
return timeout_express;
}
public void setTimeout_express(String timeout_express) {
this.timeout_express = timeout_express;
}
public String getProduct_code() {
return product_code;
}
public void setProduct_code(String product_code) {
this.product_code = product_code;
}
}
4:编写支付业务代码service实现类
/**
* 支付宝支付接口
* @param orderNo 订单号
* @param payMoney 支付金额
* @return
*/
@Override
public String pay(AlipayBean alipayBean) {
try {
AlipayClient alipayClient = new DefaultAlipayClient(
AlipayConfig.url,//支付宝网管
AlipayConfig.app_id,//appid
AlipayConfig.private_key,//私钥
AlipayConfig.format,//json格式
AlipayConfig.charset,//编码格式
AlipayConfig.public_key,//公钥
AlipayConfig.sign_type);//签名方式
AlipayTradeAppPayRequest appPayRequest = new AlipayTradeAppPayRequest();
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("我是测试数据");
model.setSubject("App支付测试Java");
//请保证OutTradeNo值每次保证唯一
model.setOutTradeNo(alipayBean.getOut_trade_no());//订单号
model.setTimeoutExpress("30m");//超时时间 自定义
model.setTotalAmount(alipayBean.getTotal_amount());//前台传的支付金额 string类型
model.setProductCode("QUICK_MSECURITY_PAY");//写死
appPayRequest.setBizModel(model);
appPayRequest.setNotifyUrl(AlipayConfig.notify_url);//回调地址
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(appPayRequest);
System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
return response.getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
String msg = e.getMessage();
return msg;
}
}
5:回调方法
/**
* 米币商城回调地址(学员端)
* @param request
* @param response
* @return
* @throws IOException
*/
@PostMapping("/notifyMibiMall01")
public void notifyMibiMall01(HttpServletRequest request, HttpServletResponse response) throws IOException{
logger.info("米币商城学员端支付宝异步回调开始==============");
//1:从支付宝异步回调中取值
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
Map<String,String[]> aliParams = request.getParameterMap();
//用于存放转化后的参数集合
Map<String,String> conversionParams = new HashMap<>();
for (Iterator<String> iter = aliParams.keySet().iterator();iter.hasNext();){
String key = iter.next();
String[] values = aliParams.get(key);
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"), "uft-8");
conversionParams.put(key, valueStr);
}
logger.info("返回参数的集合conversionParams=="+conversionParams);
String status = alipayService.notifyMibiMall01(conversionParams);
if (status.equals("success")){
out.write("success".getBytes());
}else {
out.write("fail".getBytes());
}
out.flush();
out.close();
}
/**
* 米币商城回调地址(学员端)
* @param conversionParams
* @return
*/
@Override
public String notifyMibiMall01(Map<String, String> conversionParams) {
logger.info("支付宝异步请求处理逻辑==============");
boolean signVerified = false;//签名验证(对支付宝返回的数据验证,确定是支付宝返回的)
try {
//调用SDK验证签名
signVerified = AlipaySignature.rsaCheckV1(conversionParams,AlipayConfig.public_key,AlipayConfig.charset,AlipayConfig.sign_type);
} catch (AlipayApiException e) {
logger.info("验签失败====================");
e.printStackTrace();
}
String userId ="";
Map<String,String> extrasMap = new HashMap<>();
//对延签进行处理
if (signVerified){
logger.info("验签通过==============");
//获取需要保存的数据
String addId = conversionParams.get("app_id");//支付宝分配给开发者的应用id
String notifyTime = conversionParams.get("notify_time");//通知时间 yyyy-mm-dd hh:mm:ss
String gmtCreate = conversionParams.get("gmt_create");//交易创建时间
// String gmtRefund = conversionParams.get("gmt_refund");// 交易退款时间
//String gmtClose = conversionParams.get("gmt_close");// 交易结束时间
String tradeNo = conversionParams.get("trade_no");// 支付宝的交易号
String outTradeNo = conversionParams.get("out_trade_no");// 获取商户之前传给支付宝的订单号(商户系统的唯一订单号)
//String outBizNo = conversionParams.get("out_biz_no");// 商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)
String buyerLogonId = conversionParams.get("buyer_logon_id");// 买家支付宝账号
String buyerId = conversionParams.get("buyer_id"); //买家支付宝用户号(唯一)
String sellerId = conversionParams.get("seller_id");// 卖家支付宝用户号
String sellerEmail = conversionParams.get("seller_email");// 卖家支付宝账号
String totalAmount = conversionParams.get("total_amount");// 订单金额:本次交易支付的订单金额,单位为人民币(元)
String receiptAmount = conversionParams.get("receipt_amount");// 实收金额:商家在交易中实际收到的款项,单位为元
//String invoiceAmount = conversionParams.get("invoice_amount");// 开票金额:用户在交易中支付的可开发票的金额
String buyerPayAmount = conversionParams.get("buyer_pay_amount");// 付款金额:用户在交易中支付的金额
String tradeStatus = conversionParams.get("trade_status");// 获取交易状态
//判断交易结果
if (tradeStatus.equals("TRADE_SUCCESS")){
FanMibiOrder fanMibiOrder = new FanMibiOrder();
fanMibiOrder.setOrderNo(outTradeNo);
fanMibiOrder.setType(2);
fanMibiOrderMapper.updateFanMibiOrder(fanMibiOrder);//修改订单状态为已完成
fanMibiOrder = fanMibiOrderMapper.selectFanMibiOrderById(outTradeNo);
Integer mibi = fanMibiOrder.getMibi()==null?0:fanMibiOrder.getMibi();
userId=fanMibiOrder.getUserId();
String companyId = fanMibiOrder.getCompanyId();
//插入米币记录
FanStuHave fanStuHave = new FanStuHave();
fanStuHave.setId(CommonUtil.getUUID());
fanStuHave.setMibi(-mibi);
fanStuHave.setType(2);
fanStuHave.setRemark("米币商城");
fanStuHave.setCompanyId(companyId);
fanStuHave.setCreateTime(new Date());
fanStuHave.setStudentId(userId);
fanStuHaveMapper.insertFanStuHave(fanStuHave);
redisUtils.delete(Constants.REDIS_STUDENT_HAVE+userId+2);
try {
jpushStudentService.sendCustomPush("米币商城","付款成功",extrasMap,userId);
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
}
return "success";
}
try {
jpushStudentService.sendCustomPush("米币商城","付款失败",extrasMap,userId);
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
}
return "fail";
}
try {
jpushStudentService.sendCustomPush("米币商城","付款失败",extrasMap,userId);
} catch (APIConnectionException e) {
e.printStackTrace();
} catch (APIRequestException e) {
e.printStackTrace();
}
return "fail";
}
返回的参数放入测试工具,可以调用沙箱环境支付宝支付,说明开发成功
下面是测试工具地址
https://alipaybbs.oss-cn-hangzhou.aliyuncs.com/1807/thread/60_191_eb31b639a0caf31.zip