代码下载地址 https://gitee.com/zscat/mallplus
关注公众号获取微服务版本下载地址和部署方式
1,各种微信支付方式接口
package com.zscat.mallplus.pay.controller.wxpay;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.jfinal.kit.StrKit;
import com.zscat.mallplus.core.enums.SignType;
import com.zscat.mallplus.core.enums.TradeType;
import com.zscat.mallplus.core.kit.*;
import com.zscat.mallplus.enums.OrderStatus;
import com.zscat.mallplus.exception.ApiMallPlusException;
import com.zscat.mallplus.oms.entity.OmsOrder;
import com.zscat.mallplus.oms.entity.OmsPayments;
import com.zscat.mallplus.oms.service.IOmsOrderItemService;
import com.zscat.mallplus.oms.service.IOmsOrderService;
import com.zscat.mallplus.oms.service.IOmsPaymentsService;
import com.zscat.mallplus.pay.entity.H5SceneInfo;
import com.zscat.mallplus.pay.entity.WxPayBean;
import com.zscat.mallplus.pay.vo.AjaxResult;
import com.zscat.mallplus.ums.entity.SysAppletSet;
import com.zscat.mallplus.ums.entity.UmsMember;
import com.zscat.mallplus.ums.mapper.SysAppletSetMapper;
import com.zscat.mallplus.ums.service.IUmsMemberService;
import com.zscat.mallplus.util.JsonUtils;
import com.zscat.mallplus.utils.CommonResult;
import com.zscat.mallplus.wxpay.WxPayApi;
import com.zscat.mallplus.wxpay.WxPayApiConfig;
import com.zscat.mallplus.wxpay.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>mallplus Pay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>mallplus Pay 交流群: 320860169</p>
*
* <p>Node.js 版: https://gitee.com/javen205/TNW</p>
*
* <p>微信支付 Demo</p>
*
* @author Javen
*/
@RestController
@RequestMapping("api/wxPay")
public class WxPayController extends AbstractWxPayApiController {
private static final String USER_PAYING = "USERPAYING";
private Logger log = LoggerFactory.getLogger(this.getClass());
@Resource
private IOmsOrderService orderService;
@Resource
private IUmsMemberService umsMemberService;
@Resource
private IOmsOrderItemService orderItemService;
@Autowired
private IOmsPaymentsService paymentsService;
@Resource
private SysAppletSetMapper appletSetMapper;
private String notifyUrl = "http://java.chengguo.link:8081/api";
private String refundNotifyUrl;
@Override
public WxPayApiConfig getApiConfig() {
WxPayApiConfig apiConfig = null;
try {
OmsPayments payments = paymentsService.getById(1);
if (payments != null) {
WxPayBean wxPayBean = JsonUtils.jsonToPojo(payments.getParams(), WxPayBean.class);
apiConfig = WxPayApiConfig.builder()
.appId(wxPayBean.getAppId())
.mchId(wxPayBean.getMchId())
.partnerKey(wxPayBean.getPartnerKey())
.certPath(wxPayBean.getCertPath())
.domain(wxPayBean.getDomain())
.build();
}
notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
} catch (Exception e) {
WxPayBean wxPayBean = new WxPayBean();
wxPayBean.setAppId("wx8321531c6046c924");
wxPayBean.setMchId("1533901051");
wxPayBean.setDomain("http://www.yjlive.cn/api/api");
wxPayBean.setPartnerKey("shen9136shen9136shen9136shen9136");
apiConfig = WxPayApiConfig.builder()
.appId(wxPayBean.getAppId())
.mchId(wxPayBean.getMchId())
.partnerKey(wxPayBean.getPartnerKey())
.certPath(wxPayBean.getCertPath())
.domain(wxPayBean.getDomain())
.build();
notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
}
return apiConfig;
}
public WxPayApiConfig getApiConfig1() {
WxPayApiConfig apiConfig = null;
try {
SysAppletSet appletSet = appletSetMapper.selectOne(new QueryWrapper<>());
if (null == appletSet) {
throw new ApiMallPlusException("没有设置支付配置");
}
if (appletSet != null) {
apiConfig = WxPayApiConfig.builder()
.appId(appletSet.getAppid())
.mchId(appletSet.getMchid())
.partnerKey(appletSet.getPaySignKey())
.certPath(appletSet.getCertname())
.domain(appletSet.getNotifyurl())
.build();
}
notifyUrl = apiConfig.getDomain().concat("/wxPay/payNotify");
refundNotifyUrl = apiConfig.getDomain().concat("/wxPay/refundNotify");
} catch (Exception e) {
}
return apiConfig;
}
@GetMapping("/getKey")
@ResponseBody
public void getKey() {
// return new CommonResult().success(WxPayApi.getSignKey(wxPayBean.getMchId(), wxPayBean.getPartnerKey(), SignType.MD5));
}
/**
* 微信H5 支付
* 注意:必须再web页面中发起支付且域名已添加到开发配置中
*/
@RequestMapping(value = "/wapPay", method = {RequestMethod.POST, RequestMethod.GET})
public Object wapPay(HttpServletRequest request, @RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) throws IOException {
try {
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
H5SceneInfo sceneInfo = new H5SceneInfo();
WxPayApiConfig wxPayApiConfig = this.getApiConfig1();
H5SceneInfo.H5 h5_info = new H5SceneInfo.H5();
h5_info.setType("Wap");
//此域名必须在商户平台--"产品中心"--"开发配置"中添加
h5_info.setWap_url(wxPayApiConfig.getDomain());
h5_info.setWap_name("mallplus Pay VIP 充值");
sceneInfo.setH5Info(h5_info);
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus 微信H5 支付")
.attach(orderInfo.getStoreName())
.out_trade_no(orderInfo.getOrderSn())
.total_fee(orderInfo.getPayAmount().multiply(new BigDecimal(100)).intValue()+"")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.MWEB.getTradeType())
.scene_info(JSON.toJSONString(sceneInfo))
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
log.info("params:"+params.toString());
String xmlResult = WxPayApi.pushOrder(false, params);
log.info("xmlResult:"+xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String return_code = result.get("return_code");
String return_msg = result.get("return_msg");
if (!WxPayKit.codeIsOk(return_code)) {
throw new RuntimeException(return_msg);
}
String result_code = result.get("result_code");
if (!WxPayKit.codeIsOk(result_code)) {
throw new RuntimeException(return_msg);
}
// 以下字段在return_code 和result_code都为SUCCESS的时候有返回
String prepayId = result.get("prepay_id");
String webUrl = result.get("mweb_url");
log.info("prepay_id:" + prepayId + " mweb_url:" + webUrl);
// response.sendRedirect(webUrl);
return new CommonResult().success(webUrl);
}catch (Exception e){
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
/**
* openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
*/
@RequestMapping(value = "/authCodeToOpenid", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object authCodeToOpenid(@RequestParam(value = "wxH5Appid", required = true, defaultValue = "0")String wxH5Appid,
@RequestParam(value = "wxH5Secret", required = true, defaultValue = "0")String wxH5Secret,
@RequestParam(value = "code", required = true, defaultValue = "0")String code) {
return new CommonResult().success(umsMemberService.webLogin( wxH5Appid, wxH5Secret, code));
}
/**
* 公众号支付
*/
@RequestMapping(value = "/webPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object webPay(HttpServletRequest request, @RequestParam(value = "orderId", required = true, defaultValue = "0") Long orderId) {
try {
String totalFee = "0.01";
// openId,采用 网页授权获取 access_token API:SnsAccessTokenApi获取
UmsMember member = umsMemberService.getNewCurrentMember();
String openId = member.getWeixinOpenid();
if (StrUtil.isEmpty(openId)) {
return new CommonResult().failed("openId is null");
}
if (StrUtil.isEmpty(totalFee)) {
return new CommonResult().failed("请输入数字金额");
}
String ip = IpKit.getRealIp(request);
if (StrUtil.isEmpty(ip)) {
ip = "127.0.0.1";
}
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
System.out.println(orderInfo.getPayAmount().multiply(new BigDecimal(100)).toPlainString());
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus 公众号支付") // mallplus Pay 让支付触手可及-公众号支付
.attach(orderInfo.getStoreName())
.out_trade_no(orderInfo.getOrderSn())
.total_fee(orderInfo.getPayAmount().multiply(new BigDecimal(100)).intValue()+"")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.JSAPI.getTradeType())
.openid(openId)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info("xmlResult:"+xmlResult);
Map<String, String> resultMap = WxPayKit.xmlToMap(xmlResult);
String returnCode = resultMap.get("return_code");
String returnMsg = resultMap.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
return new CommonResult().failed(returnMsg);
}
String resultCode = resultMap.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return new CommonResult().failed(returnMsg);
}
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = resultMap.get("prepay_id");
Map<String, String> packageParams = WxPayKit.prepayIdCreateSign(prepayId, wxPayApiConfig.getAppId(),
wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String jsonStr = JSON.toJSONString(packageParams);
return new CommonResult().success(jsonStr);
}catch (Exception e){
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
/**
* 扫码模式一
*/
@RequestMapping(value = "/scanCode1", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object scanCode1(HttpServletRequest request, HttpServletResponse response,
@RequestParam("productId") String productId) {
try {
if (StrKit.isBlank(productId)) {
return new CommonResult().failed("productId is null");
}
WxPayApiConfig config = this.getApiConfig();
//获取扫码支付(模式一)url
String qrCodeUrl = WxPayKit.bizPayUrl(config.getPartnerKey(), config.getAppId(), config.getMchId(), productId);
log.info(qrCodeUrl);
//生成二维码保存的路径
String name = "payQRCode1.png";
log.info(ResourceUtils.getURL("classpath:").getPath());
Boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H,
"png", 200, 200,
ResourceUtils.getURL("classpath:").getPath().concat("static").concat(File.separator).concat(name));
if (encode) {
//在页面上显示
return new AjaxResult().success(name);
}
} catch (Exception e) {
e.printStackTrace();
return new CommonResult().failed("系统异常:" + e.getMessage());
}
return null;
}
/**
* 扫码支付模式一回调
*/
@RequestMapping(value = "/scanCodeNotify", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String scanCodeNotify(HttpServletRequest request, HttpServletResponse response) {
try {
String result = HttpKit.readData(request);
log.info("scanCodeNotify>>>" + result);
/**
* 获取返回的信息内容中各个参数的值
*/
Map<String, String> map = WxPayKit.xmlToMap(result);
for (String key : map.keySet()) {
log.info("key= " + key + " and value= " + map.get(key));
}
String appId = map.get("appid");
String openId = map.get("openid");
String mchId = map.get("mch_id");
String isSubscribe = map.get("is_subscribe");
String nonceStr = map.get("nonce_str");
String productId = map.get("product_id");
String sign = map.get("sign");
Map<String, String> packageParams = new HashMap<String, String>(6);
packageParams.put("appid", appId);
packageParams.put("openid", openId);
packageParams.put("mch_id", mchId);
packageParams.put("is_subscribe", isSubscribe);
packageParams.put("nonce_str", nonceStr);
packageParams.put("product_id", productId);
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
String packageSign = WxPayKit.createSign(packageParams, wxPayApiConfig.getPartnerKey(), SignType.MD5);
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus Pay 让支付触手可及-扫码支付模式一")
.attach("Node.js 版:https://gitee.com/javen205/TNW")
.out_trade_no(WxPayKit.generateStr())
.total_fee("1")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.NATIVE.getTradeType())
.openid(openId)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info("统一下单:" + xmlResult);
/**
* 发送信息给微信服务器
*/
Map<String, String> payResult = WxPayKit.xmlToMap(xmlResult);
String returnCode = payResult.get("return_code");
String resultCode = payResult.get("result_code");
if (WxPayKit.codeIsOk(returnCode) && WxPayKit.codeIsOk(resultCode)) {
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = payResult.get("prepay_id");
Map<String, String> prepayParams = new HashMap<String, String>(10);
prepayParams.put("return_code", "SUCCESS");
prepayParams.put("appid", appId);
prepayParams.put("mch_id", mchId);
prepayParams.put("nonceStr", System.currentTimeMillis() + "");
prepayParams.put("prepay_id", prepayId);
String prepaySign = null;
if (sign.equals(packageSign)) {
prepayParams.put("result_code", "SUCCESS");
} else {
prepayParams.put("result_code", "FAIL");
//result_code为FAIL时,添加该键值对,value值是微信告诉客户的信息
prepayParams.put("err_code_des", "订单失效");
}
prepaySign = WxPayKit.createSign(prepayParams, wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
prepayParams.put("sign", prepaySign);
String xml = WxPayKit.toXml(prepayParams);
log.error(xml);
return xml;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 扫码支付模式二
*/
@RequestMapping(value = "/scanCode2", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object scanCode2(HttpServletRequest request, HttpServletResponse response,
@RequestParam("total_fee") String totalFee) {
if (StrKit.isBlank(totalFee)) {
return new CommonResult().failed("支付金额不能为空");
}
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus Pay 让支付触手可及-扫码支付模式二")
.attach("Node.js 版:https://gitee.com/javen205/TNW")
.out_trade_no(WxPayKit.generateStr())
.total_fee("1")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.NATIVE.getTradeType())
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info("统一下单:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("return_code");
String returnMsg = result.get("return_msg");
System.out.println(returnMsg);
if (!WxPayKit.codeIsOk(returnCode)) {
return new CommonResult().failed("error:" + returnMsg);
}
String resultCode = result.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return new CommonResult().failed("error:" + returnMsg);
}
//生成预付订单success
String qrCodeUrl = result.get("code_url");
String name = "payQRCode2.png";
Boolean encode = QrCodeKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
request.getSession().getServletContext().getRealPath("/") + File.separator + name);
if (encode) {
//在页面上显示
return new AjaxResult().success(name);
}
return null;
}
/**
* 刷卡支付
*/
@RequestMapping(value = "/micropay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object microPay(HttpServletRequest request, HttpServletResponse response) {
String authCode = request.getParameter("auth_code");
String totalFee = request.getParameter("total_fee");
if (StrKit.isBlank(totalFee)) {
return new CommonResult().failed("支付金额不能为空");
}
if (StrKit.isBlank(authCode)) {
return new CommonResult().failed("auth_code参数错误");
}
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = MicroPayModel.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus Pay 让支付触手可及-刷卡支付")
.attach("Node.js 版:https://gitee.com/javen205/TNW")
.out_trade_no(WxPayKit.generateStr())
.total_fee("1")
.spbill_create_ip(ip)
.auth_code(authCode)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.microPay(false, params);
//同步返回结果
log.info("xmlResult:" + xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("return_code");
String returnMsg = result.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
//通讯失败
String errCode = result.get("err_code");
if (StrKit.notBlank(errCode)) {
//用户支付中,需要输入密码
if (USER_PAYING.equals(errCode)) {
//等待5秒后调用【查询订单API】
}
}
log.info("提交刷卡支付失败>>" + xmlResult);
return new CommonResult().failed(returnMsg);
}
String resultCode = result.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
log.info("支付失败>>" + xmlResult);
String errCodeDes = result.get("err_code_des");
return new CommonResult().failed(errCodeDes);
}
//支付成功
return new AjaxResult().success(xmlResult);
}
/**
* 微信APP支付
*/
@RequestMapping(value = "/appPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object appPay(HttpServletRequest request,@RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) {
try {
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("微信APP支付")
.attach(orderInfo.getStoreName())
.out_trade_no(orderInfo.getOrderSn())
.total_fee(orderInfo.getPayAmount().multiply(new BigDecimal(100)).intValue()+"")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.APP.getTradeType())
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info(xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("return_code");
String returnMsg = result.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
return new CommonResult().failed(returnMsg);
}
String resultCode = result.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return new CommonResult().failed(returnMsg);
}
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = result.get("prepay_id");
Map<String, String> packageParams = WxPayKit.appPrepayIdCreateSign(wxPayApiConfig.getAppId(), wxPayApiConfig.getMchId(), prepayId,
wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
// WxAppPayDto dto = JsonUtils.map2pojo(packageParams, WxAppPayDto.class);
log.info("返回apk的参数:" + JsonUtils.objectToJson(packageParams));
return new CommonResult().success(JsonUtils.objectToJson(packageParams));
}catch (Exception e){
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
/**
* 微信小程序支付
*/
@RequestMapping(value = "/miniAppPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public Object miniAppPay(HttpServletRequest request,@RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) {
try {
//需要通过授权来获取openId
UmsMember user = umsMemberService.getNewCurrentMember();
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
SysAppletSet appletSet = appletSetMapper.selectOne(new QueryWrapper<>());
if (null == appletSet) {
throw new ApiMallPlusException("没有设置支付配置");
}
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
WxPayBean wxPayApiConfig = new WxPayBean();
wxPayApiConfig.setAppId(appletSet.getAppid());
wxPayApiConfig.setMchId(appletSet.getMchid());
wxPayApiConfig.setDomain(appletSet.getNotifyurl());
wxPayApiConfig.setPartnerKey(appletSet.getPaySignKey());
Map<String, String> params = UnifiedOrderModel
.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.body("mallplus-小程序支付")
.attach("Node.js 版:https://gitee.com/javen205/TNW")
.out_trade_no(orderInfo.getOrderSn())
.total_fee(orderInfo.getPayAmount().multiply(new BigDecimal(100)).intValue()+"")
.spbill_create_ip(ip)
.notify_url(notifyUrl)
.trade_type(TradeType.JSAPI.getTradeType())
.openid(user.getWeixinOpenid())
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String xmlResult = WxPayApi.pushOrder(false, params);
log.info(xmlResult);
Map<String, String> result = WxPayKit.xmlToMap(xmlResult);
String returnCode = result.get("return_code");
String returnMsg = result.get("return_msg");
if (!WxPayKit.codeIsOk(returnCode)) {
return new CommonResult().failed(returnMsg);
}
String resultCode = result.get("result_code");
if (!WxPayKit.codeIsOk(resultCode)) {
return new CommonResult().failed(returnMsg);
}
// 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
String prepayId = result.get("prepay_id");
Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
String jsonStr = JSON.toJSONString(packageParams);
log.info("小程序支付的参数:" + jsonStr);
return new CommonResult().success(packageParams);
}catch (Exception e){
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
/**
* 企业付款到零钱
*/
@RequestMapping(value = "/transfer", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String transfer(HttpServletRequest request, @RequestParam("openId") String openId) {
String ip = IpKit.getRealIp(request);
if (StrKit.isBlank(ip)) {
ip = "127.0.0.1";
}
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = TransferModel.builder()
.mch_appid(wxPayApiConfig.getAppId())
.mchid(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.partner_trade_no(WxPayKit.generateStr())
.openid(openId)
.check_name("NO_CHECK")
.amount("100")
.desc("mallplus Pay 让支付触手可及-企业付款")
.spbill_create_ip(ip)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256, false);
// 提现
String transfers = WxPayApi.transfers(params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
log.info("提现结果:" + transfers);
Map<String, String> map = WxPayKit.xmlToMap(transfers);
String returnCode = map.get("return_code");
String resultCode = map.get("result_code");
if (WxPayKit.codeIsOk(returnCode) && WxPayKit.codeIsOk(resultCode)) {
// 提现成功
} else {
// 提现失败
}
return transfers;
}
/**
* 查询企业付款到零钱
*/
@RequestMapping(value = "/transferInfo", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String transferInfo(@RequestParam("partner_trade_no") String partnerTradeNo) {
try {
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = GetTransferInfoModel.builder()
.nonce_str(WxPayKit.generateStr())
.partner_trade_no(partnerTradeNo)
.mch_id(wxPayApiConfig.getMchId())
.appid(wxPayApiConfig.getAppId())
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256, false);
return WxPayApi.getTransferInfo(params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取RSA加密公钥
*/
@RequestMapping(value = "/getPublicKey", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String getPublicKey() {
try {
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = new HashMap<String, String>(4);
params.put("mch_id", wxPayApiConfig.getMchId());
params.put("nonce_str", String.valueOf(System.currentTimeMillis()));
params.put("sign_type", "MD5");
String createSign = WxPayKit.createSign(params, wxPayApiConfig.getPartnerKey(), SignType.MD5);
params.put("sign", createSign);
return WxPayApi.getPublicKey(params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 企业付款到银行卡
*/
@RequestMapping(value = "/payBank", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String payBank() {
try {
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
//通过WxPayApi.getPublicKey接口获取RSA加密公钥
//假设获取到的RSA加密公钥为PUBLIC_KEY(PKCS#8格式)
final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6Bl76IwSvBTiibZ+CNRUA6BfahMshZ0WJpHD1GpmvcQjeN6Yrv6c9eIl6gB4nU3isN7bn+LmoVTpH1gHViaV2YyG/zXj4z4h7r+V+ezesMqqorEg38BCNUHNmhnw4/C0I4gBAQ4x0SJOGnfKGZKR9yzvbkJtvEn732JcEZCbdTZmaxkwlenXvM+mStcJaxBCB/h5xJ5VOF5nDbTPzLphIpzddr3zx/Jxjna9QB1v/YSKYXn+iuwruNUXGCvvxBWaBGKrjOdRTRy9adWOgNmtuYDQJ2YOfG8PtPe06ELKjmr2CfaAGrKKUroyaGvy3qxAV0PlT+UQ4ADSXWt/zl0o5wIDAQAB";
Map<String, String> params = new HashMap<String, String>(10);
params.put("mch_id", wxPayApiConfig.getMchId());
params.put("partner_trade_no", System.currentTimeMillis() + "");
params.put("nonce_str", System.currentTimeMillis() + "");
//收款方银行卡号
params.put("enc_bank_no", RsaKit.encryptByPublicKeyByWx("银行卡号", PUBLIC_KEY));
//收款方用户名
params.put("enc_true_name", RsaKit.encryptByPublicKeyByWx("银行卡持有人姓名", PUBLIC_KEY));
//收款方开户行
params.put("bank_code", "1001");
params.put("amount", "1");
params.put("desc", "mallplus Pay 让支付触手可及-付款到银行卡");
params.put("sign", WxPayKit.createSign(params, wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256));
return WxPayApi.payBank(params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询企业付款到银行
*/
@RequestMapping(value = "/queryBank", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String queryBank(@RequestParam("partner_trade_no") String partnerTradeNo) {
try {
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = new HashMap<String, String>(4);
params.put("mch_id", wxPayApiConfig.getMchId());
params.put("partner_trade_no", partnerTradeNo);
params.put("nonce_str", System.currentTimeMillis() + "");
params.put("sign", WxPayKit.createSign(params, wxPayApiConfig.getPartnerKey(), SignType.MD5));
return WxPayApi.queryBank(params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 微信退款
*/
@RequestMapping(value = "/refund", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String refund(@RequestParam("transactionId") String transactionId,
@RequestParam("out_trade_no") String outTradeNo) {
if (StrKit.isBlank(outTradeNo) && StrKit.isBlank(transactionId)) {
return "transactionId、out_trade_no二选一";
}
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = RefundModel.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.transaction_id(transactionId)
.out_trade_no(outTradeNo)
.out_refund_no(WxPayKit.generateStr())
.total_fee("1")
.refund_fee("1")
.notify_url(refundNotifyUrl)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
return WxPayApi.orderRefund(false, params, wxPayApiConfig.getCertPath(), wxPayApiConfig.getMchId());
}
/**
* 微信退款查询
*/
@RequestMapping(value = "/refundQuery", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String refundQuery(@RequestParam("transactionId") String transactionId,
@RequestParam("out_trade_no") String outTradeNo,
@RequestParam("out_refund_no") String outRefundNo,
@RequestParam("refund_id") String refundId) {
WxPayApiConfig wxPayApiConfig = this.getApiConfig();
Map<String, String> params = RefundQueryModel.builder()
.appid(wxPayApiConfig.getAppId())
.mch_id(wxPayApiConfig.getMchId())
.nonce_str(WxPayKit.generateStr())
.transaction_id(transactionId)
.out_trade_no(outTradeNo)
.out_refund_no(outRefundNo)
.refund_id(refundId)
.build()
.createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
return WxPayApi.orderRefundQuery(false, params);
}
/**
* 退款通知
*/
@RequestMapping(value = "/refundNotify", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String refundNotify(HttpServletRequest request) {
String xmlMsg = HttpKit.readData(request);
log.info("微信退款通知=" + xmlMsg);
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
String returnCode = params.get("return_code");
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
if (WxPayKit.codeIsOk(returnCode)) {
String reqInfo = params.get("req_info");
String decryptData = WxPayKit.decryptData(reqInfo, this.getApiConfig().getPartnerKey());
log.info("退款通知解密后的数据=" + decryptData);
// 更新订单信息
// 发送通知等
Map<String, String> xml = new HashMap<String, String>(2);
xml.put("return_code", "SUCCESS");
xml.put("return_msg", "OK");
return WxPayKit.toXml(xml);
}
return null;
}
/**
* 异步通知
*/
@RequestMapping(value = "/payNotify", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String payNotify(HttpServletRequest request) {
String xmlMsg = HttpKit.readData(request);
Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
log.info("微信支付通知=" + params);
String returnCode = params.get("return_code");
//订单编号
String out_trade_no = params.get("out_trade_no");
OmsOrder param = new OmsOrder();
param.setOrderSn(out_trade_no);
List<OmsOrder> list = orderService.list(new QueryWrapper<>(param));
OmsOrder orderInfo = list.get(0);
orderInfo.setStatus(OrderStatus.TO_DELIVER.getValue());
orderInfo.setPaymentTime(new Date());
// 注意重复通知的情况,同一订单号可能收到多次通知,请注意一定先判断订单状态
// 注意此处签名方式需与统一下单的签名类型一致
if (WxPayKit.verifyNotify(params, this.getApiConfig().getPartnerKey(), SignType.HMACSHA256)) {
if (WxPayKit.codeIsOk(returnCode)) {
// 更新订单信息
orderService.updateById(orderInfo);
// 发送通知等
Map<String, String> xml = new HashMap<String, String>(2);
xml.put("return_code", "SUCCESS");
xml.put("return_msg", "OK");
return WxPayKit.toXml(xml);
}else {
log.error("订单" + out_trade_no + "支付失败");
orderService.releaseStock(orderInfo);
}
}
return null;
}
}
2.支持各种方式的支付宝支付接口
package com.zscat.mallplus.pay.controller.alipay;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zscat.mallplus.alipay.AliPayApi;
import com.zscat.mallplus.alipay.AliPayApiConfig;
import com.zscat.mallplus.alipay.AliPayApiConfigKit;
import com.zscat.mallplus.alipay.AliPayBean;
import com.zscat.mallplus.core.kit.PayKit;
import com.zscat.mallplus.core.kit.RsaKit;
import com.zscat.mallplus.enums.OrderStatus;
import com.zscat.mallplus.exception.ApiMallPlusException;
import com.zscat.mallplus.oms.entity.OmsOrder;
import com.zscat.mallplus.oms.entity.OmsPayments;
import com.zscat.mallplus.oms.service.IOmsOrderItemService;
import com.zscat.mallplus.oms.service.IOmsOrderService;
import com.zscat.mallplus.oms.service.IOmsPaymentsService;
import com.zscat.mallplus.pay.utils.StringUtils;
import com.zscat.mallplus.ums.service.IUmsMemberService;
import com.zscat.mallplus.util.JsonUtils;
import com.zscat.mallplus.utils.CommonResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>mallplus Pay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>mallplus Pay 交流群: 320860169</p>
*
* <p>Node.js 版: https://gitee.com/javen205/TNW</p>
*
* <p>支付宝支付 Demo</p>
*
* @author Javen
*/
@RestController
@RequestMapping("/api/aliPay")
public class AliPayController extends AbstractAliPayApiController {
private static final Logger log = LoggerFactory.getLogger(AliPayController.class);
String domain = "";
String privateKey = "";
String publicKey = "";
String appId = "";
@Resource
private IOmsOrderService orderService;
@Resource
private IUmsMemberService memberService;
@Resource
private IOmsOrderItemService orderItemService;
@Autowired
private IOmsPaymentsService paymentsService;
@Override
public AliPayApiConfig getApiConfig() {
AliPayApiConfig aliPayApiConfig = null;
try {
//aliPayApiConfig = AliPayApiConfigKit.getApiConfig(aliPayBean.getAppId());
OmsPayments payments = paymentsService.getById(2);
if (payments != null) {
AliPayBean aliPayBean = JsonUtils.jsonToPojo(payments.getParams(), AliPayBean.class);
aliPayApiConfig = AliPayApiConfig.builder()
.setAppId(aliPayBean.getAppId())
.setAliPayPublicKey(aliPayBean.getPublicKey())
.setCharset("UTF-8")
.setPrivateKey(aliPayBean.getPrivateKey())
.setServiceUrl(aliPayBean.getServerUrl())
.setSignType("RSA2")
.build();
domain = aliPayBean.getDomain();
privateKey = aliPayBean.getPrivateKey();
publicKey = aliPayBean.getPublicKey();
appId = aliPayBean.getAppId();
}
} catch (Exception e) {
AliPayBean aliPayBean = new AliPayBean();
aliPayBean.setAppId("2017010804923732");
aliPayBean.setDomain("http://www.yjlive.cn/api/api");
aliPayBean.setServerUrl("https://openapi.alipay.com/gateway.do");
aliPayBean.setPublicKey("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzQsSWsgXJO7HTWLd/8Y9de6kPBlGqvnBCdL6N8pbg9TZ5LDQOpPxef940nY/dHQiBw61bVZQULSps2mhOs7xjebhEJfhXiGV+aZBjacxr+qJ4EpM/pjH3MrfA8IB5MpB9OFEeOTGos3FMzeQHPiqeeDAIDEFs4fO112/3OWfCD6rLI88H0FoDqZ4oSsAkniFZAW1IjwW9Whgicgo4v3IjcWV+k4eFCSCORpnNKjLbsco0qJic1FaHqbkccnpW8/40j/Vo/ZZG/qCDyZ/Lt7+OKDgO8dzelFfG/IoAuEMGsgb26tCAZMVyjMxXUgLrqnTESAx6121pqy1fiwyMC6cRwIDAQAB\n");
aliPayBean.setPrivateKey("MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDNCxJayBck7sdNYt3/xj117qQ8GUaq+cEJ0vo3yluD1NnksNA6k/F5/3jSdj90dCIHDrVtVlBQtKmzaaE6zvGN5uEQl+FeIZX5pkGNpzGv6ongSkz+mMfcyt8DwgHkykH04UR45MaizcUzN5Ac+Kp54MAgMQWzh87XXb/c5Z8IPqssjzwfQWgOpnihKwCSeIVkBbUiPBb1aGCJyCji/ciNxZX6Th4UJII5Gmc0qMtuxyjSomJzUVoepuRxyelbz/jSP9Wj9lkb+oIPJn8u3v44oOA7x3N6UV8b8igC4QwayBvbq0IBkxXKMzFdSAuuqdMRIDHrXbWmrLV+LDIwLpxHAgMBAAECggEACYIM7NbAc/76kPUXtEeeC/zv8rV9WGpScEEvRy0EB130aK1mSoEXvn+BO8kt8hl8hnVBJnvNJ6DpCZ/JUS/NdbYSE7HnSnUmPjhea9In9K9ci2EGpvuwsOVbaBI0Akb6vf9ALJb3Ow9tqI1YCm/hf9tTLWr4h7Wxer0nK3geYsRn6O92AKFYjxvImR/qj9sr2DNHg83lX/2YkdDuxhLWF8oTZzunhqvEWo17mEcCrFpx/vY3bME+ZMG/IAtp89PFXXsNHii4nI0buR8mx4z6CgIetgL0qFJUeMUir1ZKn+uAyy9Jv1V9Bu7R07LXsjlZlA/xnew5ie/42iyGcusYiQKBgQDvRiPWCX0eEe4rVcPHAZJ1d/jsOGwvhzmE4TUQdnjVU0bKdgY4hHS9BrvjCTAWmzEE0siS85inzQj26DGGNr5U+D0HYfTEymNQNBMLin/ApLvNPL7xzFdpA19sVvatVV+c5Vl9JaVGuBraK69Q7Cz/6OQwXU1NGQWohZhOyMX6MwKBgQDbYF2BM7npaXFQVbigGmXgdvLHeWdZag7M4dB0lHsqGWAdtQzIIn05q9rBWNMusEfal/eZKuvmoXaDquh/g0VDCmmxxIE4OS9j37g64/4QbWJxwM8rDzA6Z58peng7CUse9Pb3Q/F8JQ/EvniEa6JT1qXWGWhQcpGsACCZEYYpnQKBgGQPAsFo6md+vAhnLx2zbJmu9+tglO0zMTx+KQCfalxbHMlhnaxYx7Ccdkm09+UcNN19f97j+zyAo3UNGFi139YMkQjbT85TjEBn5mb3HgFjYh2rf3YCK7OAc5EMtM87WmZ0Cn4pFfqC1sfRaNkASrkhnPsUqVTKV/FnHJAlqZS9AoGBAJgAKCmajolEzwerrXX5dHdX05YU72AL1V9uY0IzkzczR96tkMKm6v9nrPXktsaVy+ORAjS1gahWXciTRe78JKRz9ZH/ps0vCj/4Ri0/xczaDajlwGWEa5U8MRLLUb0ODmfPscLX591tzIQ0uUp/TYUrp9I13opHJ9n2aJ/GfaAdAoGARUzil6jIO3mASNaH7MPR4MqvxMO0LuBwaVxR1mvM7GtDDDYWU3fTJ6lFpyr340cYgEmHAVnLezbLmP75Jqo42j7H5V3BplPITSSik9ti3WOHFlPRYsZBewL7cJb4VX5oRrbfOX8to9wfw2TvofHE82NDtQn9fQUoFpqKlkIraL4=\n");
aliPayApiConfig = AliPayApiConfig.builder()
.setAppId(aliPayBean.getAppId())
.setAliPayPublicKey(aliPayBean.getPublicKey())
.setCharset("UTF-8")
.setPrivateKey(aliPayBean.getPrivateKey())
.setServiceUrl(aliPayBean.getServerUrl())
.setSignType("RSA2")
.build();
domain = aliPayBean.getDomain();
privateKey = aliPayBean.getPrivateKey();
publicKey = aliPayBean.getPublicKey();
appId = aliPayBean.getAppId();
}
return aliPayApiConfig;
}
@RequestMapping("")
@ResponseBody
public String index() {
return "欢迎使用 mallplus Pay 中的支付宝支付 -By Javen <br/><br> 交流群:320860169";
}
@RequestMapping("/test")
@ResponseBody
public AliPayApiConfig test() {
AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();
String charset = aliPayApiConfig.getCharset();
log.info("charset>" + charset);
return aliPayApiConfig;
}
/**
* app支付
*/
@RequestMapping(value = "/appPay")
@ResponseBody
public Object appPay(@RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) {
try {
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setBody("zhifu");
model.setSubject("mallplus app支付");
model.setOutTradeNo(orderInfo.getOrderSn());
model.setTimeoutExpress("30m");
model.setTotalAmount(orderInfo.getPayAmount().floatValue()+"");
model.setPassbackParams("callback params");
model.setProductCode("QUICK_MSECURITY_PAY");
String order = AliPayApi.appPayToResponse(model, domain + "/aliPay/notify_url",this.getApiConfig()).getBody();
System.out.println(JSONObject.toJSONString(orderInfo));
return new CommonResult().success(order);
} catch (AlipayApiException e) {
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
@RequestMapping(value = "/wapPayNoSdk")
@ResponseBody
public void wapPayNoSdk(HttpServletResponse response,@RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) {
try {
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
throw new ApiMallPlusException("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
throw new ApiMallPlusException( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
throw new ApiMallPlusException( "订单已支付,请不要重复操作" );
}
AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();
Map<String, String> paramsMap = new HashMap<>();
paramsMap.put("app_id", aliPayApiConfig.getAppId());
paramsMap.put("method", "alipay.trade.wap.pay");
paramsMap.put("return_url", domain + "aliPay/return_url");
paramsMap.put("charset", aliPayApiConfig.getCharset());
paramsMap.put("sign_type", aliPayApiConfig.getSignType());
paramsMap.put("timestamp", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
paramsMap.put("version", "1.0");
paramsMap.put("notify_url", domain + "/aliPay/notify_url");
Map<String, String> bizMap = new HashMap<>();
bizMap.put("body", "mallplus 聚合支付-H5");
bizMap.put("subject", "mallplus Pay 让支付触手可及");
bizMap.put("out_trade_no", StringUtils.getOutTradeNo());
bizMap.put("total_amount", orderInfo.getPayAmount().toString());
bizMap.put("product_code", "QUICK_WAP_WAY");
paramsMap.put("biz_content", JSON.toJSONString(bizMap));
String content = PayKit.createLinkString(paramsMap);
System.out.println(content);
String encrypt = RsaKit.encryptByPrivateKey(content, aliPayApiConfig.getPrivateKey());
// encrypt = AlipaySignature.rsaSign(content,aliPayApiConfig.getPrivateKey(), "UTF-8","RSA2");
// System.out.println(encrypt);
paramsMap.put("sign", encrypt);
String url = aliPayApiConfig.getServiceUrl() + "?" + PayKit.createLinkString(paramsMap, true);
System.out.println(url);
response.sendRedirect(url);
} catch (Exception e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/wapPay")
@ResponseBody
public Object wapPay(HttpServletResponse response,@RequestParam(value = "orderId", required = true, defaultValue = "0") Long orderId) {
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
return new CommonResult().failed("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
return new CommonResult().failed( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
return new CommonResult().failed( "订单已支付,请不要重复操作" );
}
String body = orderInfo.getGoodsName();
String subject = "mallplus支付测试";
String passbackParams = "1";
String returnUrl = domain + "/aliPay/return_url";
String notifyUrl = domain + "/aliPay/notify_url";
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setBody(subject);
model.setSubject(subject);
model.setTotalAmount(orderInfo.getPayAmount().floatValue()+"");
model.setPassbackParams(passbackParams);
model.setOutTradeNo(orderInfo.getOrderSn());
model.setProductCode(orderInfo.getOrderSn());
try {
return new CommonResult().success(AliPayApi.wapPayStr( model, returnUrl, notifyUrl,this.getApiConfig()));
} catch (Exception e) {
e.printStackTrace();
return new CommonResult().failed(e.getMessage());
}
}
/**
* PC支付
*/
@RequestMapping(value = "/pcPay")
@ResponseBody
public void pcPay(HttpServletResponse response ,@RequestParam(value = "orderId", required = true, defaultValue = "0") Long orderId) {
try {
OmsOrder orderInfo = orderService.getById(orderId);
if (null == orderInfo) {
throw new ApiMallPlusException("订单已取消" );
}
if (orderInfo.getStatus() == OrderStatus.CLOSED.getValue()) {
throw new ApiMallPlusException( "订单已已关闭,请不要重复操作" );
}
if (orderInfo.getStatus() != OrderStatus.INIT.getValue()) {
throw new ApiMallPlusException( "订单已支付,请不要重复操作" );
}
String returnUrl = domain + "/aliPay/return_url";
String notifyUrl = domain + "/aliPay/notify_url";
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setOutTradeNo(orderInfo.getOrderSn());
model.setProductCode("FAST_INSTANT_TRADE_PAY");
model.setTotalAmount(orderInfo.getPayAmount().floatValue()+"");
model.setSubject("Javen PC支付测试");
model.setBody("Javen mallplus Pay PC支付测试");
model.setPassbackParams("passback_params");
/**
* 花呗分期相关的设置,测试环境不支持花呗分期的测试
* hb_fq_num代表花呗分期数,仅支持传入3、6、12,其他期数暂不支持,传入会报错;
* hb_fq_seller_percent代表卖家承担收费比例,商家承担手续费传入100,用户承担手续费传入0,仅支持传入100、0两种,其他比例暂不支持,传入会报错。
*/
ExtendParams extendParams = new ExtendParams();
extendParams.setHbFqNum("3");
extendParams.setHbFqSellerPercent("0");
model.setExtendParams(extendParams);
AliPayApi.tradePage(response, model, notifyUrl, returnUrl,this.getApiConfig());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 统一收单交易支付接口接口
*
* @param authCode
* @param scene
* @return
*/
@RequestMapping(value = "/tradePay")
@ResponseBody
public Object tradePay(@RequestParam("auth_code") String authCode, @RequestParam("scene") String scene) {
String subject = null;
String waveCode = "wave_code";
String barCode = "bar_code";
if (scene.equals(waveCode)) {
subject = "Javen 支付宝声波支付测试";
} else if (scene.equals(barCode)) {
subject = "Javen 支付宝条形码支付测试";
}
String totalAmount = "100";
String notifyUrl = domain + "/aliPay/notify_url";
AlipayTradePayModel model = new AlipayTradePayModel();
model.setAuthCode(authCode);
model.setSubject(subject);
model.setTotalAmount(totalAmount);
model.setOutTradeNo(StringUtils.getOutTradeNo());
model.setScene(scene);
try {
return new CommonResult().success(AliPayApi.tradePayToResponse(model, notifyUrl,this.getApiConfig()).getBody());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 扫码支付
*/
@RequestMapping(value = "/tradePrecreatePay")
@ResponseBody
public String tradePrecreatePay() {
String subject = "Javen 支付宝扫码支付测试";
String totalAmount = "86";
String storeId = "123";
String notifyUrl = domain + "/aliPay/notify_url";
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setSubject(subject);
model.setTotalAmount(totalAmount);
model.setStoreId(storeId);
model.setTimeoutExpress("5m");
model.setOutTradeNo(StringUtils.getOutTradeNo());
try {
String resultStr = AliPayApi.tradePrecreatePayToResponse(model, notifyUrl,this.getApiConfig()).getBody();
JSONObject jsonObject = JSONObject.parseObject(resultStr);
return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 单笔转账到支付宝账户
* https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.54Ty29&
* treeId=193&articleId=106236&docType=1
*/
@RequestMapping(value = "/transfer")
@ResponseBody
public boolean transfer() {
boolean isSuccess = false;
String totalAmount = "66";
AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
model.setOutBizNo(StringUtils.getOutTradeNo());
model.setPayeeType("ALIPAY_LOGONID");
model.setPayeeAccount("[email protected]");
model.setAmount(totalAmount);
model.setPayerShowName("测试退款");
model.setPayerRealName("沙箱环境");
model.setRemark("javen测试单笔转账到支付宝");
try {
isSuccess = AliPayApi.transfer(model,this.getApiConfig());
} catch (Exception e) {
e.printStackTrace();
}
return isSuccess;
}
/**
* 资金授权冻结接口
*/
@RequestMapping(value = "/authOrderFreeze")
@ResponseBody
public Object authOrderFreeze(@RequestParam("auth_code") String authCode) {
try {
AlipayFundAuthOrderFreezeModel model = new AlipayFundAuthOrderFreezeModel();
model.setOutOrderNo(StringUtils.getOutTradeNo());
model.setOutRequestNo(StringUtils.getOutTradeNo());
model.setAuthCode(authCode);
model.setAuthCodeType("bar_code");
model.setOrderTitle("资金授权冻结-By mallplus Pay");
model.setAmount("36");
model.setProductCode("PRE_AUTH");
return new CommonResult().success(AliPayApi.authOrderFreezeToResponse(model,this.getApiConfig()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 红包协议支付接口
* https://docs.open.alipay.com/301/106168/
*/
@RequestMapping(value = "/agreementPay")
@ResponseBody
public Object agreementPay() {
try {
AlipayFundCouponOrderAgreementPayModel model = new AlipayFundCouponOrderAgreementPayModel();
model.setOutOrderNo(StringUtils.getOutTradeNo());
model.setOutRequestNo(StringUtils.getOutTradeNo());
model.setOrderTitle("红包协议支付接口-By mallplus Pay");
model.setAmount("36");
model.setPayerUserId("2088102180432465");
return new CommonResult().success(AliPayApi.fundCouponOrderAgreementPayToResponse(model,this.getApiConfig()));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 下载对账单
*/
@RequestMapping(value = "/dataDataserviceBill")
@ResponseBody
public Object dataDataserviceBill(@RequestParam("billDate") String billDate) {
try {
AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
model.setBillType("trade");
model.setBillDate(billDate);
return new CommonResult().success(AliPayApi.billDownloadurlQuery(model,this.getApiConfig()));
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 退款
*/
@RequestMapping(value = "/tradeRefund")
@ResponseBody
public Object tradeRefund() {
try {
AlipayTradeRefundModel model = new AlipayTradeRefundModel();
model.setOutTradeNo("081014283315023");
model.setTradeNo("2017081021001004200200273870");
model.setRefundAmount("86.00");
model.setRefundReason("正常退款");
return new CommonResult().success(AliPayApi.tradeRefundToResponse(model,this.getApiConfig()).getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 交易查询
*/
@RequestMapping(value = "/tradeQuery")
@ResponseBody
public boolean tradeQuery() {
boolean isSuccess = false;
try {
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo("081014283315023");
model.setTradeNo("2017081021001004200200273870");
isSuccess = AliPayApi.tradeQueryToResponse(model,this.getApiConfig()).isSuccess();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return isSuccess;
}
@RequestMapping(value = "/tradeQueryByStr")
@ResponseBody
public Object tradeQueryByStr(@RequestParam("out_trade_no") String outTradeNo) {
AlipayTradeQueryModel model = new AlipayTradeQueryModel();
model.setOutTradeNo(outTradeNo);
try {
return new CommonResult().success(AliPayApi.tradeQueryToResponse(model,this.getApiConfig()).getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 创建订单
* {"alipay_trade_create_response":{"code":"10000","msg":"Success","out_trade_no":"081014283315033","trade_no":"2017081021001004200200274066"},"sign":"ZagfFZntf0loojZzdrBNnHhenhyRrsXwHLBNt1Z/dBbx7cF1o7SZQrzNjRHHmVypHKuCmYifikZIqbNNrFJauSuhT4MQkBJE+YGPDtHqDf4Ajdsv3JEyAM3TR/Xm5gUOpzCY7w+RZzkHevsTd4cjKeGM54GBh0hQH/gSyhs4pEN3lRWopqcKkrkOGZPcmunkbrUAF7+AhKGUpK+AqDw4xmKFuVChDKaRdnhM6/yVsezJFXzlQeVgFjbfiWqULxBXq1gqicntyUxvRygKA+5zDTqE5Jj3XRDjVFIDBeOBAnM+u03fUP489wV5V5apyI449RWeybLg08Wo+jUmeOuXOA=="}
*/
@RequestMapping(value = "/tradeCreate")
@ResponseBody
public Object tradeCreate(@RequestParam("out_trade_no") String outTradeNo) {
String notifyUrl = domain + "/aliPay/notify_url";
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
model.setOutTradeNo(outTradeNo);
model.setTotalAmount("88.88");
model.setBody("Body");
model.setSubject("Javen 测试统一收单交易创建接口");
//买家支付宝账号,和buyer_id不能同时为空
model.setBuyerLogonId("[email protected]");
try {
AlipayTradeCreateResponse response = AliPayApi.tradeCreateToResponse(model, notifyUrl,this.getApiConfig());
return new CommonResult().success(response.getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 撤销订单
*/
@RequestMapping(value = "/tradeCancel")
@ResponseBody
public Object tradeCancel() {
boolean isSuccess = false;
try {
AlipayTradeCancelModel model = new AlipayTradeCancelModel();
model.setOutTradeNo("081014283315033");
model.setTradeNo("2017081021001004200200274066");
isSuccess = AliPayApi.tradeCancelToResponse(model,this.getApiConfig()).isSuccess();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return new CommonResult().success(isSuccess);
}
/**
* 关闭订单
*/
@RequestMapping(value = "/tradeClose")
@ResponseBody
public Object tradeClose(@RequestParam("out_trade_no") String outTradeNo, @RequestParam("trade_no") String tradeNo) {
try {
AlipayTradeCloseModel model = new AlipayTradeCloseModel();
model.setOutTradeNo(outTradeNo);
model.setTradeNo(tradeNo);
return new CommonResult().success(AliPayApi.tradeCloseToResponse(model,this.getApiConfig()).getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 结算
*/
@RequestMapping(value = "/tradeOrderSettle")
@ResponseBody
public Object tradeOrderSettle(@RequestParam("trade_no") String tradeNo) {
try {
AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
model.setOutRequestNo(StringUtils.getOutTradeNo());
model.setTradeNo(tradeNo);
return new CommonResult().success(AliPayApi.tradeOrderSettleToResponse(model,this.getApiConfig()).getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取应用授权URL并授权
*/
@RequestMapping(value = "/toOauth")
@ResponseBody
public void toOauth(HttpServletResponse response) {
try {
String redirectUri = domain + "/aliPay/redirect_uri";
String oauth2Url = AliPayApi.getOauth2Url(appId, redirectUri);
response.sendRedirect(oauth2Url);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 应用授权回调
*/
@RequestMapping(value = "/redirect_uri")
@ResponseBody
public Object redirectUri(@RequestParam("app_id") String appId, @RequestParam("app_auth_code") String appAuthCode) {
try {
System.out.println("app_id:" + appId);
System.out.println("app_auth_code:" + appAuthCode);
//使用app_auth_code换取app_auth_token
AlipayOpenAuthTokenAppModel model = new AlipayOpenAuthTokenAppModel();
model.setGrantType("authorization_code");
model.setCode(appAuthCode);
return new CommonResult().success(AliPayApi.openAuthTokenAppToResponse(model,this.getApiConfig()).getBody());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 查询授权信息
*/
@RequestMapping(value = "/openAuthTokenAppQuery")
@ResponseBody
public Object openAuthTokenAppQuery(@RequestParam("app_auth_token") String appAuthToken) {
try {
AlipayOpenAuthTokenAppQueryModel model = new AlipayOpenAuthTokenAppQueryModel();
model.setAppAuthToken(appAuthToken);
return new CommonResult().success(AliPayApi.openAuthTokenAppQueryToResponse(model,this.getApiConfig()).getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
/**
* 批量付款到支付宝账户有密接口
*/
@RequestMapping(value = "/batchTrans")
@ResponseBody
public void batchTrans(HttpServletResponse response) {
try {
String signType = "MD5";
String notifyUrl = domain + "/aliPay/notify_url";
Map<String, String> params = new HashMap<>(15);
params.put("partner", "PID");
params.put("sign_type", signType);
params.put("notify_url", notifyUrl);
params.put("account_name", "xxx");
params.put("detail_data", "流水号1^收款方账号1^收款账号姓名1^付款金额1^备注说明1|流水号2^收款方账号2^收款账号姓名2^付款金额2^备注说明2");
params.put("batch_no", String.valueOf(System.currentTimeMillis()));
params.put("batch_num", 1 + "");
params.put("batch_fee", 10.00 + "");
params.put("email", "[email protected]");
AliPayApi.batchTrans(params, privateKey, signType, response);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 地铁购票核销码发码
*/
@RequestMapping(value = "/voucherGenerate")
@ResponseBody
public String voucherGenerate(@RequestParam("tradeNo") String tradeNo) {
try {
//需要支付成功的订单号
// String tradeNo = getPara("tradeNo");
AlipayCommerceCityfacilitatorVoucherGenerateModel model = new AlipayCommerceCityfacilitatorVoucherGenerateModel();
model.setCityCode("440300");
model.setTradeNo(tradeNo);
model.setTotalFee("8");
model.setTicketNum("2");
model.setTicketType("oneway");
model.setSiteBegin("001");
model.setSiteEnd("002");
model.setTicketPrice("4");
return AliPayApi.voucherGenerateToResponse(model,this.getApiConfig()).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
return null;
}
@RequestMapping(value = "/return_url")
@ResponseBody
public Object returnUrl(HttpServletRequest request) {
try {
// 获取支付宝GET过来反馈信息
Map<String, String> map = AliPayApi.toMap(request);
System.out.println("return_url");
System.out.println(map.toString());
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
boolean verifyResult = AlipaySignature.rsaCheckV1(map, publicKey, "UTF-8",
"RSA2");
if (verifyResult) {
// TODO 请在这里加上商户的业务逻辑程序代码
System.out.println("return_url 验证成功");
return new CommonResult().success();
} else {
System.out.println("return_url 验证失败");
// TODO
return new CommonResult().failed();
}
} catch (AlipayApiException e) {
e.printStackTrace();
return "failure";
}
}
@RequestMapping(value = "/notify_url")
@ResponseBody
public Object notifyUrl(HttpServletRequest request) {
try {
// 获取支付宝POST过来反馈信息
Map<String, String> params = AliPayApi.toMap(request);
System.out.println("notify_url");
System.out.println(params.toString());
for (Map.Entry<String, String> entry : params.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
String out_trade_no = params.get("out_trade_no");
OmsOrder param = new OmsOrder();
param.setOrderSn(out_trade_no);
List<OmsOrder> list = orderService.list(new QueryWrapper<>(param));
OmsOrder orderInfo = list.get(0);
orderInfo.setStatus(OrderStatus.TO_DELIVER.getValue());
orderInfo.setPaymentTime(new Date());
boolean verifyResult = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", "RSA2");
if (verifyResult) {
// 更新订单信息
orderService.updateById(orderInfo);
// TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
System.out.println("notify_url 验证成功succcess");
return new CommonResult().success();
} else {
log.error("订单" + out_trade_no + "支付失败");
orderService.releaseStock(orderInfo);
// TODO
return new CommonResult().failed();
}
} catch (AlipayApiException e) {
e.printStackTrace();
return "failure";
}
}
}
3.京东支付 接口
package com.zscat.mallplus.pay.controller.jdpay;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.XmlUtil;
import com.zscat.mallplus.jdpay.JdPayApi;
import com.zscat.mallplus.jdpay.kit.JdPayKit;
import com.zscat.mallplus.jdpay.model.*;
import com.zscat.mallplus.pay.entity.JdPayBean;
import com.zscat.mallplus.pay.vo.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import java.util.Date;
import java.util.Map;
/**
* <p>mallplus Pay 让支付触手可及,封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
*
* <p>不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完成支付模块的开发,可轻松嵌入到任何系统里。 </p>
*
* <p>mallplus Pay 交流群: 320860169</p>
*
* <p>Node.js 版: https://gitee.com/javen205/TNW</p>
*
* <p>微信支付 Demo</p>
*
* @author Javen
*/
@Controller
@RequestMapping("/api/JDPay")
public class JdPayController {
@Autowired
JdPayBean jdPayBean;
private Logger log = LoggerFactory.getLogger(this.getClass());
@RequestMapping("")
@ResponseBody
public String index() {
log.info("欢迎使用 mallplus Pay 中的京东支付 -By Javen <br/><br> 交流群:320860169");
log.info(jdPayBean.toString());
return ("欢迎使用 mallplus Pay 中的京东支付 -By Javen <br/><br> 交流群:320860169");
}
@GetMapping("/test")
@ResponseBody
public JdPayBean test() {
return jdPayBean;
}
/**
* App 支付
*
* @return
*/
@RequestMapping(value = "/appPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult appPay() {
String reqXml = UniOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("mallplus Pay 让支付触手可及")
.tradeDesc("https://gitee.com/javen205/mallplus Pay")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount("1")
.orderType("1")
.currency("CNY")
.note("备注")
.notifyUrl("http://jdpaydemo.jd.com/asynNotify.htm")
.tradeType("GEN")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
// 执行请求
String resultData = JdPayApi.uniOrder(reqXml);
log.info("resultData:" + resultData);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(resultData);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
// 将 xml 转化为 map
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
log.info("result toMap>" + toMap);
String orderId = (String) toMap.get("orderId");
StringBuilder sb = new StringBuilder();
sb.append("merchant=").append(jdPayBean.getMchId());
sb.append("&orderId=").append(orderId);
sb.append("&key=").append("test");
String sign = JdPayKit.md5LowerCase(sb.toString());
return new AjaxResult().success(new AppParams(orderId, jdPayBean.getMchId(), "123456789",
sign, "123456789"));
}
/**
* PC H5 支付
*
* @param payType
* @return
*/
@RequestMapping(value = "/saveOrder", method = {RequestMethod.POST, RequestMethod.GET})
public ModelAndView saveOrder(@RequestParam("payType") String payType) {
ModelAndView mv = new ModelAndView();
Map<String, String> map = SaveOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("mallplus Pay")
.tradeDesc("mallplus Pay 让支付触手可及")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount("10000")
.orderType("0")
.currency("CNY")
.note("mallplus Pay 了解一下")
.callbackUrl("https://jdpay.com")
.notifyUrl("https://jdpay.com")
.userId("mallplus Pay001")
.build()
.createSign(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey());
mv.addObject("map", map);
mv.addObject("payUrl", payType.equals("pc") ? JdPayApi.PC_SAVE_ORDER_URL : JdPayApi.H5_SAVE_ORDER_URL);
mv.setViewName("jd_pc_h5.html");
return mv;
}
/**
* 商户二维码支付
*/
@RequestMapping(value = "/customerPay", method = {RequestMethod.POST, RequestMethod.GET})
public ModelAndView customerPay() {
ModelAndView mv = new ModelAndView();
Map<String, String> map = CustomerPayModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.tradeName("mallplus Pay")
.tradeDesc("mallplus Pay 让支付触手可及")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
// .amount("1000")
.orderType("0")
.currency("CNY")
.note("mallplus Pay 了解一下")
.notifyUrl("https://jdpay.com")
.build()
.createSign(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey());
mv.addObject("map", map);
mv.addObject("payUrl", JdPayApi.CUSTOMER_PAY_URL);
mv.setViewName("jd_customer_pay.html");
return mv;
}
@RequestMapping(value = "/queryOrder", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult queryOrder(@RequestParam("tradeType") String tradeType,
@RequestParam("oTradeNum") String oTradeNum,
@RequestParam("tradeNum") String tradeNum) {
String reqXml = QueryOrderModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(tradeNum)
.tradeType(tradeType)
.oTradeNum(oTradeNum)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.queryOrder(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@RequestMapping(value = "/fkmPay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult fkmPay(@RequestParam("token") String token,
@RequestParam("amount") String amount) {
String reqXml = FkmModel.builder()
.token(token)
.version("V2.0")
.merchant(jdPayBean.getMchId())
.device("mallplus Pay Dev")
.tradeNum(System.currentTimeMillis() + "")
.tradeName("mallplus Pay 刷卡支付")
.tradeDesc("mallplus Pay 了解一下")
.tradeTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.amount(amount)
.currency("CNY")
.note("备注")
.notifyUrl("https://gitee.com/javen205/mallplus Pay")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.fkmPay(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@RequestMapping(value = "/userRelation", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult userRelation(@RequestParam("userId") String userId,
@RequestParam("type") String type) {
String reqXml = UserRelationModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.userId(userId)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String result = null;
if ("get".equals(type)) {
result = JdPayApi.getUserRelation(reqXml);
} else {
result = JdPayApi.cancelUserRelation(reqXml);
}
log.info(result);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(result);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
System.out.println(toMap);
return new AjaxResult().success(decrypt);
}
@RequestMapping(value = "/refund", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult refund(@RequestParam("amount") String amount,
@RequestParam("oTradeNum") String oTradeNum,
@RequestParam("tradeNum") String tradeNum) {
System.out.println(Base64.encode(FileUtil.readBytes(jdPayBean.getCertPath())));
String reqXml = RefundModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(tradeNum)
.oTradeNum(oTradeNum)
.amount(amount)
.currency("CNY")
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String queryResult = JdPayApi.refund(reqXml);
log.info("queryResult:" + queryResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(queryResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
return new AjaxResult().success(decrypt);
}
@RequestMapping(value = "/queryBaiTiaoFq", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult queryBaiTiaoFq(@RequestParam("amount") String amount) {
String reqXml = QueryBaiTiaoFqModel.builder()
.version("V2.0")
.merchant(jdPayBean.getMchId())
.tradeNum(System.currentTimeMillis() + "")
.amount(amount)
.build()
.genReqXml(jdPayBean.getRsaPrivateKey(), jdPayBean.getDesKey(), "V2.0", jdPayBean.getMchId());
String baiTiaoResult = JdPayApi.queryBaiTiaoFq(reqXml);
log.info(baiTiaoResult);
// 解析响应的 xml 数据
Map<String, String> map = JdPayKit.parseResp(baiTiaoResult);
String code = map.get("code");
String encrypt = map.get("encrypt");
if (!"000000".equals(code)) {
String desc = map.get("desc");
return new AjaxResult().addError(desc);
}
// 解密并验证签名
String decrypt = JdPayKit.decrypt(jdPayBean.getRsaPublicKey(), jdPayBean.getDesKey(), encrypt);
log.info("decrypt>" + decrypt);
Map<String, Object> toMap = XmlUtil.xmlToMap(decrypt);
System.out.println(toMap);
return new AjaxResult().success(decrypt);
}
}
4.银联支付
package com.zscat.mallplus.pay.controller.unionpay;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.zscat.mallplus.pay.vo.AjaxResult;
import com.zscat.mallplus.unionpay.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
@Controller
@RequestMapping("/api/unionPay")
public class UnionPayController {
private static final Logger logger = LoggerFactory.getLogger(UnionPayController.class);
private AjaxResult ajax = new AjaxResult();
/**
* 将回调参数转为Map
*
* @param notifyStr
* @return {Map<String, String>}
*/
public static Map<String, String> getAllRequestParamToMap(final String notifyStr) {
Map<String, String> res = new HashMap<String, String>();
try {
logger.info("收到通知报文:" + notifyStr);
String[] kvs = notifyStr.split("&");
for (String kv : kvs) {
String[] tmp = kv.split("=");
if (tmp.length >= 2) {
String key = tmp[0];
String value = URLDecoder.decode(tmp[1], "UTF-8");
res.put(key, value);
}
}
} catch (UnsupportedEncodingException e) {
logger.info("getAllRequestParamStream.UnsupportedEncodingException error: " + e.getClass() + ":"
+ e.getMessage());
}
return res;
}
/**
* 组装请求,返回报文字符串用于显示
*
* @param data
* @return {String}
*/
public static String getHtmlResult(Map<String, String> data) {
TreeMap<String, String> tree = new TreeMap<String, String>();
Iterator<Map.Entry<String, String>> it = data.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, String> en = it.next();
tree.put(en.getKey(), en.getValue());
}
it = tree.entrySet().iterator();
StringBuffer sf = new StringBuffer();
while (it.hasNext()) {
Map.Entry<String, String> en = it.next();
String key = en.getKey();
String value = en.getValue();
if ("respCode".equals(key)) {
sf.append("<b>" + key + "=" + value + "</br></b>");
} else
sf.append(key + "=" + value + "</br>");
}
return sf.toString();
}
public static String readData(HttpServletRequest request) {
BufferedReader br = null;
try {
StringBuilder result = new StringBuilder();
br = request.getReader();
for (String line; (line = br.readLine()) != null; ) {
if (result.length() > 0) {
result.append("\n");
}
result.append(line);
}
return result.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@RequestMapping("")
@ResponseBody
public String index() {
logger.info("欢迎使用mallplus Pay银联支付 - by Javen");
return "欢迎使用mallplus Pay银联支付 - by Javen";
}
/**
* PC网关支付
* B2C跟B2B查询区别就在于bizType的不同
*/
@RequestMapping(value = "/frontConsume", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void frontConsume(HttpServletResponse response) {
try {
Map<String, String> createMap = UnionPayApiConfig.builder()
// .setChannelType("07") 默认值就是07
.setMerId("777290058151764")
.setTxnAmt("6666")
.setReqReserved("reqReserved")
// .setFrontUrl(SDKConfig.getConfig().getFrontUrl()) 有默认值
// .setBackUrl(SDKConfig.getConfig().getBackUrl()) 有默认值
.createMap();
UnionPayApi.frontRequest(response, createMap);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* B2B的网关支付 B2C跟B2B查询区别就在于bizType的不同
*/
@RequestMapping(value = "/frontConsume2", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void frontConsume2(HttpServletResponse response) {
try {
Map<String, String> createMap = UnionPayApiConfig.builder()
.setBizType("000202")
.setChannelType("07")
.setMerId("777290058151764")
.setTxnAmt("2222")
.setReqReserved("reqReserved")
.createMap();
UnionPayApi.frontRequest(response, createMap);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* WAP支付 请在手机端访问此action
*/
@RequestMapping(value = "/wapConsume", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void wapConsume(HttpServletResponse response) {
try {
Map<String, String> createMap = UnionPayApiConfig.builder()
.setChannelType("08")
.setMerId("777290058151764")
.setTxnAmt("6868")
.setReqReserved("reqReserved")
.setFrontUrl(SDKConfig.getConfig().getFrontUrl())
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.createMap();
UnionPayApi.frontRequest(response, createMap);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* APP支付获取tn
*/
@RequestMapping(value = "/appConsume", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public AjaxResult appConsume() {
try {
Map<String, String> reqData = UnionPayApiConfig.builder()
.setChannelType("08")
.setMerId("777290058151764")
.setTxnAmt("8888")
.setReqReserved("reqReserved")
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.createMap();
Map<String, String> rspData = UnionPayApi.AppConsumeByMap(reqData);
// 应答码规范参考open.unionpay.com帮助中心 下载 产品接口规范 《平台接入接口规范-第5部分-附录》
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, "UTF-8")) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
// 成功,获取tn号
String tn = rspData.get("tn");
ajax.success(tn);
} else {
// 其他应答码为失败请排查原因或做失败处理
ajax.addError(respCode);
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
ajax.addError("验证签名失败");
}
} else {
// 未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
ajax.addError("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
logger.info("app>reqMessage>>>" + reqMessage + " rspMessage>>>" + rspMessage);
return ajax;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 订单状态查询B2C跟B2B查询区别就在于bizType的不同
*/
@RequestMapping(value = "/query", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void query(HttpServletResponse response) {
try {
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("00")
.setTxnSubType("00")
.setBizType("000301")
.setMerId("777290058151764")
// .setOrderId("1507214190872")
// .setTxnTime("20171005223630")
.setOrderId("1508488509626")
.setTxnTime("20171020163509")
.createMap();
Map<String, String> rspData = UnionPayApi.singleQueryByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, "UTF-8")) {
logger.info("验证签名成功");
if ("00".equals(rspData.get("respCode"))) {//如果查询交易成功
//处理被查询交易的应答码逻辑
String origRespCode = rspData.get("origRespCode");
if ("00".equals(origRespCode)) {
//交易成功,更新商户订单状态
} else if ("03".equals(origRespCode) ||
"04".equals(origRespCode) ||
"05".equals(origRespCode)) {
//需再次发起交易状态查询交易
} else {
//其他应答码为失败请排查原因
}
} else {//查询交易本身失败,或者未查到原交易,检查查询交易报文要素
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 订单状态查询 B2B
* B2C跟B2B查询区别就在于bizType的不同
*/
@RequestMapping(value = "/queryB2B", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void queryB2B(HttpServletResponse response) {
try {
Map<String, String> reqData = UnionPayApiConfig.builder()
.setBizType("000202")
.setTxnType("00")
.setTxnSubType("00")
.setMerId("777290058151764")
.setOrderId("1507277885640")
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))
.createMap();
Map<String, String> rspData = UnionPayApi.singleQueryByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, "UTF-8")) {
logger.info("验证签名成功");
if ("00".equals(rspData.get("respCode"))) {//如果查询交易成功
//处理被查询交易的应答码逻辑
String origRespCode = rspData.get("origRespCode");
if ("00".equals(origRespCode)) {
//交易成功,更新商户订单状态
} else if ("03".equals(origRespCode) ||
"04".equals(origRespCode) ||
"05".equals(origRespCode)) {
//需再次发起交易状态查询交易
} else {
//其他应答码为失败请排查原因
}
} else {//查询交易本身失败,或者未查到原交易,检查查询交易报文要素
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (IOException e) {
e.printStackTrace();
}
}
@RequestMapping(value = "/refund", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void refund(HttpServletResponse response) {
try {
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("04") //交易类型 04-退货 31-消费撤销
.setTxnSubType("00") //交易子类型 默认00
.setBizType("000201") //业务类型 B2C网关支付,手机wap支付
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setTxnAmt("6666")
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setOrigQryId("201710061443208788498") //****原消费交易返回的的queryId,可以从消费交易后台通知接口中或者交易状态查询接口中获取
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, "UTF-8")) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if ("00".equals(respCode)) {
//交易已受理,等待接收后台通知更新订单状态,也可以主动发起 查询交易确定交易状态。
} else if ("03".equals(respCode) ||
"04".equals(respCode) ||
"05".equals(respCode)) {
//后续需发起交易状态查询交易确定交易状态
} else {
//其他应答码为失败请排查原因
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 测试通过
* https://open.unionpay.com/ajweb/help/faq/list?id=95&level=0&from=0
* java.lang.RuntimeException: Unexpected code Response{protocol=http/1.1, code=500, message=Internal Server Error, url=https://filedownload.test.95516.com/}
*/
@RequestMapping(value = "/fileTransfer", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void fileTransfer(HttpServletResponse response) {
try {
// String settleDate = DateKit.toStr(new Date(), DateKit.UnionDateStampPattern);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setAccessType("0")
.setTxnType("76") //交易类型 76-对账文件下载
.setTxnSubType("01") //交易子类型 01-对账文件下载
.setBizType("000000") //业务类型,固定
.setMerId("700000000000001")
.setSettleDate("0119") //清算日期,如果使用正式商户号测试则要修改成自己想要获取对账文件的日期, 测试环境如果使用777290058151764商户号则固定填写0119
.setFileType("00")
.createMap();
//移除默认参数
reqData.remove("orderId");
reqData.remove("payTimeout");
reqData.remove("backUrl");
reqData.remove("channelType");
reqData.remove("currencyCode");
reqData.remove("frontUrl");
reqData.remove("txnAmt");
//重新签名
reqData = UnionPayApiConfig.builder().setSignMap(reqData);
Map<String, String> rspData = UnionPayApi.fileTransferByMap(reqData);
String fileContentDispaly = "";
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if ("00".equals(respCode)) {
String outPutDirectory = "/Users/Javen/Documents/dev/mallplus Pay";
// String outPutDirectory ="d:\\";
// 交易成功,解析返回报文中的fileContent并落地
String zipFilePath = AcpService.deCodeFileContent(rspData, outPutDirectory, DemoBase.encoding);
//对落地的zip文件解压缩并解析
List<String> fileList = DemoBase.unzip(zipFilePath, outPutDirectory);
//解析ZM,ZME文件
fileContentDispaly = "<br>获取到商户对账文件,并落地到" + outPutDirectory + ",并解压缩 <br>";
for (String file : fileList) {
if (file.indexOf("ZM_") != -1) {
List<Map<Integer, String>> ZmDataList = DemoBase.parseZMFile(file);
fileContentDispaly = fileContentDispaly + DemoBase.getFileContentTable(ZmDataList, file);
} else if (file.indexOf("ZME_") != -1) {
DemoBase.parseZMEFile(file);
}
}
//其他处理
} else {
//其他应答码为失败请排查原因
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("<html><head></br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + fileContentDispaly + "</head></html>");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 信用卡网关还款
*/
@RequestMapping(value = "/repaymentGateway", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void repaymentGateway(HttpServletResponse response) {
try {
Map<String, String> map = new HashMap<String, String>();
map.put("usr_num", "6221558812340013");//信用卡卡号
map.put("usr_num2", "6221558812340013");//重复信用卡卡号
map.put("usr_nm", "全渠道");//信用卡持卡人姓名【无特殊要求尽量不要送】这里填写错误会出现报文格式错误 (5100030)
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("13") //交易类型 04-退货 31-消费撤销 13 账单支付
.setTxnSubType("03") //交易子类型 03 信用卡还款
.setBizType("000601")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setBussCode("J1_9800_0000_1")
.setMerId("777290058151764")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setTxnAmt("1234")
.setBillQueryInfo(AcpService.base64Encode(JSONUtil.toJsonPrettyStr(map), DemoBase.encoding))
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setFrontUrl(SDKConfig.getConfig().getFrontUrl())
// .setReqReserved("mallplus Pay repaymentGateway")
.createMap();
UnionPayApi.jfFrontConsume(response, reqData);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 二维码支付
* 二维码仿真
* https://open.unionpay.com/ajweb/help/qrcodeFormPage
*/
@RequestMapping(value = "/qrCodePay", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void qrCodePay(HttpServletResponse response) {
try {
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("01")
.setTxnSubType("06")
.setBizType("000000")
.setChannelType("08") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setQrNo("6225058203886110875")
.setTermId("00000011")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setTxnAmt("2580")
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setReqReserved("mallplus Pay qrCodePay")
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("二维码支付验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
//成功,获取tn号
String tn = rspData.get("tn");
System.out.println("tn>>>>>>>" + tn);
} else {
//其他应答码为失败请排查原因或做失败处理
}
} else {
logger.error("二维码验证签名失败");
//检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 代收后台建立委托
*/
@RequestMapping(value = "/jlwtBack", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void jlwtBack(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6221558812340000", "UTF-8"); //这里测试的时候使用的是测试卡号,正式环境请使用真实卡号
//姓名,证件类型+证件号码至少二选一必送,手机号可选,贷记卡的cvn2,expired可选。
Map<String, String> customerInfoMap = new HashMap<String, String>();
customerInfoMap.put("certifTp", "01");//证件类型
customerInfoMap.put("certifId", "341126197709218366");//证件号码
customerInfoMap.put("customerNm", "互联网");//姓名
customerInfoMap.put("phoneNo", "13552535506");//手机号
//当卡号为贷记卡的时候cvn2,expired可选上送
customerInfoMap.put("cvn2", "123");//卡背面的cvn2三位数字
customerInfoMap.put("expired", "1711");
String customerInfoStr = AcpService.
getCustomerInfoWithEncrypt(customerInfoMap, null, DemoBase.encoding);
// String customerInfoStr = AcpService.
// getCustomerInfo(customerInfoMap,null,DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("72")
.setTxnSubType("11")
.setBizType("000501")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.setCustomerInfo(customerInfoStr)
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
//成功,获取tn号
String tn = rspData.get("tn");
System.out.println("tn>>>>>>>" + tn);
} else {
//其他应答码为失败请排查原因或做失败处理
}
} else {
logger.error("验证签名失败");
//检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 代收前台建立委托
*/
@RequestMapping(value = "/jlwtFront", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void jlwtFront(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6221558812340000", "UTF-8"); //这里测试的时候使用的是测试卡号,正式环境请使用真实卡号
//姓名,证件类型+证件号码至少二选一必送,手机号可选,贷记卡的cvn2,expired可选。
Map<String, String> customerInfoMap = new HashMap<String, String>();
customerInfoMap.put("certifTp", "01");//证件类型
customerInfoMap.put("certifId", "341126197709218366");//证件号码
customerInfoMap.put("customerNm", "互联网");//姓名
customerInfoMap.put("phoneNo", "13552535506");//手机号
//当卡号为贷记卡的时候cvn2,expired可选上送
customerInfoMap.put("cvn2", "123");//卡背面的cvn2三位数字
customerInfoMap.put("expired", "1711");
String customerInfoStr = AcpService.
getCustomerInfoWithEncrypt(customerInfoMap, null, DemoBase.encoding);
// String customerInfoStr = AcpService.
// getCustomerInfo(customerInfoMap,null,DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("72")
.setTxnSubType("11")
.setBizType("000501")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setFrontUrl(SDKConfig.getConfig().getFrontUrl())
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.setCustomerInfo(customerInfoStr)
.createMap();
UnionPayApi.frontRequest(response, reqData);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 解除委托关系
*/
@RequestMapping(value = "/removeWt", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void removeWt(HttpServletResponse response) {
try {
//这里测试的时候使用的是测试卡号,正式环境请使用真实卡号
String accNoEnc = AcpService.encryptData("6221558812340000", "UTF-8");
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("74")
.setTxnSubType("04")
.setBizType("000501")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
//成功
} else {
//其他应答码为失败请排查原因或做失败处理
}
} else {
logger.error("验证签名失败");
//检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 代收1102
*/
@RequestMapping(value = "/daiShou1102", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void daiShou1102(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6221558812340000", DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("11")
.setTxnSubType("02")
.setBizType("000501")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setTxnAmt("8888")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
//交易已受理(不代表交易已成功),等待接收后台通知更新订单状态,也可以主动发起 查询交易确定交易状态。
//如果是配置了敏感信息加密,如果需要获取卡号的铭文,可以按以下方法解密卡号
//String accNo1 = resmap.get("accNo");
//String accNo2 = AcpService.decryptData(accNo1, "UTF-8"); //解密卡号使用的证书是商户签名私钥证书acpsdk.signCert.path
//logger.info("解密后的卡号:"+accNo2);
} else if (("03").equals(respCode) ||
("04").equals(respCode) ||
("05").equals(respCode)) {
//后续需发起交易状态查询交易确定交易状态
} else {
//其他应答码为失败请排查原因
}
} else {
logger.error("验证签名失败");
//检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
response.getWriter().println("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + "");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 无跳转开通状态查询
*/
@RequestMapping(value = "/openQuery", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void openQuery(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6216261000000000018", DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("00")
.setTxnSubType("00")
.setBizType("000301")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.createMap();
Map<String, String> rspData = UnionPayApi.backRequestByMap(reqData);
StringBuffer parseStr = new StringBuffer("");
if (!rspData.isEmpty()) {
if (AcpService.validate(rspData, DemoBase.encoding)) {
logger.info("验证签名成功");
String respCode = rspData.get("respCode");
if (("00").equals(respCode)) {
//成功
parseStr.append("<br>解析敏感信息加密信息如下(如果有):<br>");
String customerInfo = rspData.get("customerInfo");
if (null != customerInfo) {
Map<String, String> cm = AcpService.parseCustomerInfo(customerInfo, "UTF-8");
parseStr.append("customerInfo明文: " + cm + "<br>");
}
String an = rspData.get("accNo");
if (null != an) {
an = AcpService.decryptData(an, "UTF-8");
parseStr.append("accNo明文: " + an);
}
} else {
//其他应答码为失败请排查原因或做失败处理
}
} else {
logger.error("验证签名失败");
// 检查验证签名失败的原因
}
} else {
//未返回正确的http状态
logger.error("未获取到返回报文或返回http状态码非200");
}
String reqMessage = getHtmlResult(reqData);
String rspMessage = getHtmlResult(rspData);
logger.info(getHtmlResult(rspData));
response.getWriter().write("</br>请求报文:<br/>" + reqMessage + "<br/>" + "应答报文:</br>" + rspMessage + parseStr);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 无跳转支付银联侧开通
*/
@RequestMapping(value = "/openCardFront", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void openCardFront(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6216261000000000018", "UTF-8"); //这里测试的时候使用的是测试卡号,正式环境请使用真实卡号
//姓名,证件类型+证件号码至少二选一必送,手机号可选,贷记卡的cvn2,expired可选。
Map<String, String> customerInfoMap = new HashMap<String, String>();
customerInfoMap.put("certifTp", "01");//证件类型
customerInfoMap.put("certifId", "341126197709218366");//证件号码
customerInfoMap.put("customerNm", "全渠道");//姓名
customerInfoMap.put("phoneNo", "13552535506");//手机号
String customerInfoStr = AcpService.
getCustomerInfoWithEncrypt(customerInfoMap, null, DemoBase.encoding);
// String customerInfoStr = AcpService.
// getCustomerInfo(customerInfoMap,null,DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("79")
.setTxnSubType("01")
.setBizType("000301")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setFrontUrl(SDKConfig.getConfig().getFrontUrl())
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.setCustomerInfo(customerInfoStr)
.createMap();
UnionPayApi.frontRequest(response, reqData);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 无跳转支付银联测开通并消费
*/
@RequestMapping(value = "/openAndConsume", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public void openAndConsume(HttpServletResponse response) {
try {
//卡号
String accNoEnc = AcpService.encryptData("6216261000000000018", DemoBase.encoding);
Map<String, String> reqData = UnionPayApiConfig.builder()
.setTxnType("01")
.setTxnSubType("01")
.setBizType("000301")
.setChannelType("07") //渠道类型,07-PC,08-手机
.setMerId("777290058151764")
.setAccessType("0")
.setAccType("01")
.setTxnAmt("6363")
.setOrderId(String.valueOf(System.currentTimeMillis()))//商户订单号,8-40位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生,不同于原消费
.setTxnTime(DateUtil.format(new Date(), "yyyyMMddHHmmss"))//订单发送时间,格式为YYYYMMDDhhmmss,必须取当前时间,否则会报txnTime无效
.setAccNo(accNoEnc)
.setEncryptCertId(AcpService.getEncryptCertId())//加密证书的certId,配置在acp_sdk.properties文件 acpsdk.encryptCert.path属性下
.setBackUrl(SDKConfig.getConfig().getBackUrl())
.setFrontUrl(SDKConfig.getConfig().getFrontUrl())
.createMap();
UnionPayApi.frontRequest(response, reqData);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 后台回调
*/
@RequestMapping(value = "/backRcvResponse", method = {RequestMethod.POST, RequestMethod.GET})
@ResponseBody
public String backRcvResponse(HttpServletRequest request) {
logger.info("BackRcvResponse接收后台通知开始");
String encoding = "UTF-8";
String notifyStr = readData(request);
// 获取银联通知服务器发送的后台通知参数
Map<String, String> reqParam = getAllRequestParamToMap(notifyStr);
LogUtil.printRequestLog(reqParam);
// 重要!验证签名前不要修改reqParam中的键值对的内容,否则会验签不过
if (!AcpService.validate(reqParam, encoding)) {
logger.info("后台验证签名结果[失败].");
// 验签失败,需解决验签问题
} else {
logger.info("后台验证签名结果[成功].");
// 【注:为了安全验签成功才应该写商户的成功处理逻辑】交易成功,更新商户订单状态
String orderId = reqParam.get("orderId"); // 获取后台通知的数据,其他字段也可用类似方式获取
String respCode = reqParam.get("respCode");
// 判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
logger.info("orderId>>>" + orderId + " respCode>>" + respCode);
}
logger.info("BackRcvResponse接收后台通知结束");
// 返回给银联服务器http 200 状态码
return "ok";
}
/**
* 前台回调
*/
@RequestMapping(value = "/frontRcvResponse", method = {RequestMethod.POST, RequestMethod.GET})
public String frontRcvResponse(HttpServletRequest request, HttpServletResponse response) {
try {
logger.info("FrontRcvResponse前台接收报文返回开始");
String encoding = "UTF-8";
logger.info("返回报文中encoding=[" + encoding + "]");
String readData = readData(request);
Map<String, String> respParam = getAllRequestParamToMap(readData);
// 打印请求报文
LogUtil.printRequestLog(respParam);
Map<String, String> valideData = null;
StringBuffer page = new StringBuffer();
if (null != respParam && !respParam.isEmpty()) {
Iterator<Map.Entry<String, String>> it = respParam.entrySet().iterator();
valideData = new HashMap<String, String>(respParam.size());
while (it.hasNext()) {
Map.Entry<String, String> e = it.next();
String key = (String) e.getKey();
String value = (String) e.getValue();
value = new String(value.getBytes(encoding), encoding);
page.append("<tr><td width=\"30%\" align=\"right\">" + key + "(" + key + ")</td><td>" + value
+ "</td></tr>");
valideData.put(key, value);
}
}
if (!AcpService.validate(valideData, encoding)) {
page.append("<tr><td width=\"30%\" align=\"right\">前台验证签名结果</td><td>失败</td></tr>");
logger.info("前台验证签名结果[失败].");
} else {
page.append("<tr><td width=\"30%\" align=\"right\">前台验证签名结果</td><td>成功</td></tr>");
logger.info("前台验证签名结果[成功].");
String orderId = valideData.get("orderId"); // 其他字段也可用类似方式获取
String respCode = valideData.get("respCode");
// 判断respCode=00、A6后,对涉及资金类的交易,请再发起查询接口查询,确定交易成功后更新数据库。
logger.info("orderId>>>" + orderId + " respCode>>" + respCode);
}
request.setAttribute("result", page.toString());
logger.info("FrontRcvResponse前台接收报文返回结束");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "utf8_result.html";
}
}