A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 专注的一批 中级黑马   /  2020-7-8 11:55  /  2462 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

h5端接入支付宝支付接口–spring cloud

常量配置AlipayConfig

// 请求网关地址

public static final String URL = "https://openapi.alipay.com/gateway.do";

// 编码格式

public static final String CHARSET = "UTF-8";

// 返回格式

public static final String FORMAT = "json";

// 加密类型RSA2

public static final String SIGNTYPE = "RSA2";

//h5 appid

public static final String h5APPID="*****";

//h5 支付公钥

public static final String h5_ALIPAY_PUBLIC_KEY="";

//h5 应用私钥

public static final String h5_PRIVATE_KEY="";

回调地址和通知页面地址在application.yml 配置

#h5端 阿里云支付回调(官方)这里配置回调用于处理支付成功后的逻辑

h5_alis_gf_notify_url: http://7dtuqg.natappfree.cc/uncheck/h5AliNotifyUrl

#h5端 阿里云支付成功跳转(官方)这里配置支付完后跳转的页面

h5_alis_gf_query_url: https://7dtuqg.natappfree.cc/paySuccess

支付宝支付业务层接口

public interface AliPayAppService {

//查询订单状态

Map getStatus(OrderVo orderVo);

//统一下单拉起支付

Mapgeth5AliPayOrderStr(OrderVo orderVo);

//支付完回调

String h5AliNotifyUrl(Map conversionParams);

}

支付实现 AliPayAppServiceImpl

//支付回调地址

@Value(value="${h5_alis_gf_notify_url}")

private String h5_alis_gf_notify_url;

//支付成功地址

@Value(value="${h5_alis_gf_query_url}")

private String h5_alis_gf_query_url;

/**

*

* @param orderVo 订单实体类

* @return

*/

@Override

public Map geth5AliPayOrderStr(OrderVo orderVo) {

/*********************** 先校验订单有效性*********************************/

Map map = new HashMap<>();

// 最终返回加签之后的,app需要传给支付宝app的订单信息字符串

String orderString = "0";

logger.info("h5支付宝下单,商户订单号为:" + orderVo.geteName());

//这个类对应的表存储支付完回调信息的

Alipaymentorder alipaymentOrder = new Alipaymentorder();

if (orderVo.geteId() != null) {

alipaymentOrder.setOrderId(orderVo.geteId().longValue()); // 商户订单主键

}

alipaymentOrder.setOutTradeNo(orderVo.geteName());// 商户订单号

alipaymentOrder.setTradeStatus(0);// 交易状态

//这个金额正式的需要根据订单号去查

alipaymentOrder.setTotalAmount(new BigDecimal(0.01));// 订单金额

alipaymentOrder.setRefundFee(0.00); // 总退款金额

try {

// 实例化客户端(参数:网关地址、商户appid、商户私钥、格式、编码、支付宝公钥、加密类型),为了取得预付订单信息

AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.h5APPID,

AlipayConfig.h5_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET,

AlipayConfig.h5_ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay

AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

// SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

model.setSubject("此订单"); // 商品名称

model.setOutTradeNo(orderVo.geteName()); // 商户订单号

// model.setTimeoutExpress("30m"); //交易超时时间

model.setTotalAmount("0.01");

/****************************/

model.setProductCode("QUICK_WAP_WAY"); // 销售产品码(固定值)

request.setBizModel(model);

request.setNotifyUrl(h5_alis_gf_notify_url); // 异步回调地址(后台)

request.setReturnUrl(h5_alis_gf_query_url);//设置支付成功跳转页面的地址

//ali_request.setReturnUrl(AlipayAppConfig.return_url); // 同步回调地址(APP)

//Requestcontent 是一个请求报文表与支付业务无关

Requestcontent requestcontent=new Requestcontent();

requestcontent.setContent(request.toString());//报文内容

requestcontent.setContentType(Constants.CALLBACK_ALI_APP);//支付方式

requestcontent.setContenTime(new Date());//时间

requestcontent.setEntrydetailId(orderVo.geteName());//订单号

requestcontentMapper.insertSelective(requestcontent);//添加报文

// 这里和普通的接口调用不同,使用的是sdkExecute

AlipayTradeWapPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(request); // 返回支付宝订单信息(预处理)

if(alipayTradeAppPayResponse.isSuccess()){

// 如果商家订单表没有该订单数据则添加

if (alipaymentorderService.getAlipaymentorder(orderVo.geteName()).size() == 0) {

alipaymentorderService.addAlipaymentorder(alipaymentOrder); //创建新的商户支付宝订单

}

DateAndStrUtil strUtil = DateAndStrUtil.getDateAndStr();

//DateAndStrUtil 是一个时间工具类 requestTimestamp格式为yyyy-MM-dd HH:mm:ss

String requestTimestamp = strUtil.dateToStr(new Date());

orderString = alipayTradeAppPayResponse.getBody();

map.put("orderString", "https://openapi.alipay.com/gateway.do?"+orderString+"×tamp="+requestTimestamp);

//前端直接访问orderString", "https://openapi.alipay.com/gateway.do?"+orderString+"×tamp="+requestTimestamp 即可拉起支付

return Utils.packageResponseData(MapConstants.mapSuccessCode, "拉起成功", map);

}else{

return Utils.packageResponseData(MapConstants.mapErrorCode, "拉起失败", map);

}

} catch (Exception e) {

e.printStackTrace();

logger.info("与支付宝交互出错,未能生成订单,请检查代码!");

return Utils.packageResponseData(MapConstants.mapErrorCode, "拉起失败", map);

}

}

/**

*功能描述: h5 支付宝查询订单状态

* @author

* @date 2020/7/2

* @param orderVo

* @return java.util.Map

*/

@Override

public Map getStatus(OrderVo orderVo) {

Map map=new HashMap<>();

if(Strings.isNullOrEmpty(orderVo.geteName())) {

return Utils.packageResponseData(MapConstants.mapNullCode, "订单号不能为空", map);

}

AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, AlipayConfig.h5APPID,

AlipayConfig.h5_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET,

AlipayConfig.h5_ALIPAY_PUBLIC_KEY, AlipayConfig.SIGNTYPE);

// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
外汇经纪商对比https://www.fx61.com/brokerlist

AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

request.setBizContent("{" + "\"out_trade_no\" : \"" + orderVo.geteName() + "\"}");

try {

AlipayTradeQueryResponse response = alipayClient.execute(request);

if (response.isSuccess()) {

switch (response.getTradeStatus()) // 判断交易结果

{

case "TRADE_FINISHED": // 交易结束并不可退款

map.put("status",3);

break;

case "TRADE_SUCCESS": // 交易支付成功

map.put("status",2);

break;

case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款

map.put("status",1);

break;

case "WAIT_BUYER_PAY": // 交易创建并等待买家付款

map.put("status",0);

break;

default:

break;

}

return Utils.packageResponseData(MapConstants.mapSuccessCode, "查询成功", map);

} else {

logger.info("调用支付宝查询接口失败!");

return Utils.packageResponseData(MapConstants.mapErrorCode, "调用支付宝查询接口失败!", map);

}

} catch (Exception e) {

e.printStackTrace();

return Utils.packageResponseData(MapConstants.mapErrorCode, "查询失败", map);

}

}

//h5官方支付宝异步请求逻辑处理

@Override

public String h5AliNotifyUrl(Map conversionParams) {

logger.info("h5官方支付宝异步请求逻辑处理");

// 签名验证(对支付宝返回的数据验证,确定是支付宝返回的)

boolean signVerified = false;

try {

// 调用SDK验证签名

signVerified = AlipaySignature.rsaCheckV1(conversionParams, AlipayConfig.h5_ALIPAY_PUBLIC_KEY,

AlipayConfig.CHARSET, AlipayConfig.SIGNTYPE);

} catch (AlipayApiException e) {

logger.info("验签失败 !");

e.printStackTrace();

}

// 对验签进行处理

if (signVerified) {

System.out.println("h5支付宝回调验签通过");

// 验签通过

// 获取需要保存的数据

String appId = conversionParams.get("app_id");

Alipaymentorder alipaymentOrder=getAlipayMent(conversionParams);

if (AlipayConfig.h5APPID.equals(appId)) {

EntrydetailExample entrydetailExample=new EntrydetailExample();

entrydetailExample.createCriteria().andENameEqualTo(alipaymentOrder.getOutTradeNo());

List list=entrydetailMapper.selectByExample(entrydetailExample);

alipaymentOrder.setUserId(list.get(0).geteUid());

//更新回调表中的内容

int returnResult = alipaymentorderService.updateAlipaymentorder(alipaymentOrder); // 更新交易表中状态

// 修改交易表状态,支付成功

if (returnResult > 0) {

logger.info("======h5官方支付宝更新商户订单表成功======");

return "SUCCESS";//如果不反回将会持续回调24小时

} else {

logger.info("更新表状态失败");

return "FAILED";

}

} else {

logger.info("支付宝官方建议校验的值(out_trade_no、total_amount、sellerId、app_id),不一致!返回fail");

return "FAILED";

}

} else { // 验签不通过

logger.info("验签不通过 !");

return "FAILED";

}

}

//回调用到的getAlipayMent方法

public Alipaymentorder getAlipayMent(Map conversionParams){

DateAndStrUtil dateAndStrUtil = new DateAndStrUtil();

String appId = conversionParams.get("app_id");// 支付宝分配给开发者的应用Id

String notifyTime = conversionParams.get("notify_time");// 通知时间:yyyy-MM-dd HH:mm:ss

String gmtCreate = conversionParams.get("gmt_create");// 交易创建时间:yyyy-MM-dd HH:mm:ss

String gmtPayment = conversionParams.get("gmt_payment");// 交易付款时间

String tradeNo = conversionParams.get("trade_no");// 支付宝的交易号

String outTradeNo = conversionParams.get("out_trade_no");// 获取商户之前传给支付宝的订单号(商户系统的唯一订单号)

String totalAmount = conversionParams.get("total_amount");// 订单金额:本次交易支付的订单金额,单位为人民币(元)

String receiptAmount = conversionParams.get("receipt_amount");// 实收金额:商家在交易中实际收到的款项,单位为元

String buyerPayAmount = conversionParams.get("buyer_pay_amount");// 付款金额:用户在交易中支付的金额

String tradeStatus = conversionParams.get("trade_status");// 获取交易状态

// 支付宝官方建议校验的值(out_trade_no、total_amount、sellerId、app_id)

List alipaymentOrderList = alipaymentorderService.getAlipaymentorder(outTradeNo);

Alipaymentorder alipaymentOrder = alipaymentOrderList.get(0);

alipaymentOrder.setNotifyTime(dateAndStrUtil.strToDate(notifyTime)); // 通知时间

alipaymentOrder.setGmtCreate(dateAndStrUtil.strToDate(gmtCreate)); // 交易创建时间

alipaymentOrder.setGmtPayment(dateAndStrUtil.strToDate(gmtPayment)); // 交易付款时间

//alipaymentOrder.setGmt_refund(DateUtils.parse(gmtRefund)); // 交易退款时间

//alipaymentOrder.setGmt_close(DateUtils.parse(gmtClose)); // 交易结束时间

alipaymentOrder.setTradeNo(tradeNo); // 支付宝交易号

//alipaymentOrder.setOut_biz_no(outBizNo); // 商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)

alipaymentOrder.setTotalAmount(new BigDecimal(totalAmount)); //订单金额:本次交易支付的订单金额,单位为人民币(元)

alipaymentOrder.setReceiptAmount(new BigDecimal(receiptAmount)); // 实收金额:商家在交易中实际收到的款项,单位为元

//alipaymentOrder.setInvoiceAmount(Double.parseDouble(invoiceAmount)); // 开票金额:用户在交易中支付的可开发票的金额

alipaymentOrder.setBuyerPayAmount(new BigDecimal(buyerPayAmount)); // 付款金额:用户在交易中支付的金额

Utils.getStatus(alipaymentOrder,tradeStatus);

return alipaymentOrder;

}

Utils 工具类

public class Utils {

public static void getStatus(Alipaymentorder alipaymentorder,String status){

switch (status) // 判断交易结果

{

case "TRADE_FINISHED": // 交易结束并不可退款

alipaymentorder.setTradeStatus(3);

break;

case "TRADE_SUCCESS": // 交易支付成功

alipaymentorder.setTradeStatus(2);

break;

case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款

alipaymentorder.setTradeStatus(1);

break;

case "WAIT_BUYER_PAY": // 交易创建并等待买家付款

alipaymentorder.setTradeStatus(0);

break;

default:

break;

}

}

/**

*

* Map转String

* @param map

* @return

*/

public static String getMapToString(Map map){

Set keySet = map.keySet();

//将set集合转换为数组

String[] keyArray = keySet.toArray(new String[keySet.size()]);

//给数组排序(升序)

Arrays.sort(keyArray);

//因为String拼接效率会很低的,所以转用StringBuilder

StringBuilder sb = new StringBuilder();

for (int i = 0; i < keyArray.length; i++) {

// 参数值为空,则不参与签名 这个方法trim()是去空格

if ((String.valueOf(map.get(keyArray[i]))).trim().length() > 0) {

sb.append(keyArray[i]).append(":").append(String.valueOf(map.get(keyArray[i])).trim());

}

if(i != keyArray.length-1){

sb.append(",");

}

}

return sb.toString();

}

}

支付控制层 AliPayAppController

/**

*功能描述:H5支付宝拉起支付

* @author 666

* @date 2020/7/6

* @return java.util.Map

*/

@RequestMapping(value="/geth5AliPayOrderStr",method= RequestMethod.POST)

public Map geth5AliPayOrderStr(@RequestBody OrderVo orderVo){

return aliPayAppService.geth5AliPayOrderStr(orderVo);

}

/**

*功能描述:查询订单状态

* @author 666

* @date 2020/7/2

* @param orderVo

* @return java.util.Map

*/

@RequestMapping(value = "/getStatus", method = RequestMethod.POST)

public Map getStatus(@RequestBody OrderVo orderVo) {

return aliPayAppService.getStatus(orderVo);

}

/**

* h5支付宝官方回调

* @param request

* @param response

* @return

*/

@RequestMapping(value="/h5AliNotifyUrl",method= RequestMethod.POST)

public String h5AliNotifyUrl(HttpServletRequest request, HttpServletResponse response){

logger.info("h5官方支付宝异步返回支付结果开始");

String map = aliPayAppService.h5AliNotifyUrl(Utils.map(request,response));

return map;

}

最后附上alipaymentorder表:

CREATE TABLE `alipaymentorder` (

`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',

`order_id` bigint(20) DEFAULT NULL COMMENT '商家订单主键',

`out_trade_no` varchar(255) DEFAULT NULL COMMENT '商户订单号',

`notify_time` datetime DEFAULT NULL COMMENT '通知时间',

`gmt_create` datetime DEFAULT NULL COMMENT '交易创建时间',

`gmt_payment` datetime DEFAULT NULL COMMENT '交易付款时间',

`gmt_refund` datetime DEFAULT NULL COMMENT '交易退款时间',

`gmt_close` datetime DEFAULT NULL COMMENT '交易结束时间',

`trade_no` varchar(255) DEFAULT NULL COMMENT '支付宝的交易号',

`out_biz_no` varchar(255) DEFAULT NULL COMMENT '商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)',

`seller_email` varchar(255) DEFAULT NULL COMMENT '卖家账号',

`seller_id` varchar(255) DEFAULT NULL COMMENT '卖家用户号',

`buyer_logon_id` varchar(255) DEFAULT NULL COMMENT '买家账号',

`total_amount` decimal(10,2) DEFAULT NULL COMMENT '订单金额',

`receipt_amount` decimal(10,2) DEFAULT NULL COMMENT '实收金额',

`buyer_pay_amount` decimal(10,2) DEFAULT NULL COMMENT '付款金额:用户在交易中支付的金额',

`trade_status` int(255) DEFAULT NULL COMMENT '交易状态',

`refund_fee` double(10,2) DEFAULT NULL COMMENT '总退款金额',

`buyer_id` varchar(255) DEFAULT NULL COMMENT '买家唯一用户号',

`fund_change` varchar(255) DEFAULT NULL COMMENT '本次退款是否发生了资金变化',

`store_name` varchar(255) DEFAULT NULL COMMENT '交易在支付时候的门店名称',

`trade_type` int(255) DEFAULT NULL COMMENT '1.代表微信 2.代表支付宝 3.代表苹果内购',

`user_id` int(11) DEFAULT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=206 DEFAULT CHARSET=utf8 COMMENT='商户支付宝订单表';

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马