代码下载地址  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());@Resourceprivate IOmsOrderService orderService;@Resourceprivate IUmsMemberService umsMemberService;@Resourceprivate IOmsOrderItemService orderItemService;@Autowiredprivate IOmsPaymentsService paymentsService;@Resourceprivate SysAppletSetMapper appletSetMapper;private String notifyUrl = "http://java.chengguo.link:8081/api";private String refundNotifyUrl;@Overridepublic 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")@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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();//获取扫码支付(模式一)urlString 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})@ResponseBodypublic 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})@ResponseBodypublic 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);}//生成预付订单successString 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic Object miniAppPay(HttpServletRequest request,@RequestParam(value = "orderId", required = false, defaultValue = "0") Long orderId) {try {//需要通过授权来获取openIdUmsMember 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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 = "";@Resourceprivate IOmsOrderService orderService;@Resourceprivate IUmsMemberService memberService;@Resourceprivate IOmsOrderItemService orderItemService;@Autowiredprivate IOmsPaymentsService paymentsService;@Overridepublic 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("")@ResponseBodypublic String index() {return "欢迎使用 mallplus Pay 中的支付宝支付 -By Javen  <br/><br>  交流群:320860169";}@RequestMapping("/test")@ResponseBodypublic AliPayApiConfig test() {AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();String charset = aliPayApiConfig.getCharset();log.info("charset>" + charset);return aliPayApiConfig;}/*** app支付*/@RequestMapping(value = "/appPay")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic boolean transfer() {boolean isSuccess = false;String totalAmount = "66";AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();model.setOutBizNo(StringUtils.getOutTradeNo());model.setPayeeType("ALIPAY_LOGONID");model.setPayeeAccount("abpkvd0206@sandbox.com");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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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("abpkvd0206@sandbox.com");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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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")@ResponseBodypublic 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_tokenAlipayOpenAuthTokenAppModel 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")@ResponseBodypublic 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")@ResponseBodypublic 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", "xx@xxx.com");AliPayApi.batchTrans(params, privateKey, signType, response);} catch (Exception e) {e.printStackTrace();}}/*** 地铁购票核销码发码*/@RequestMapping(value = "/voucherGenerate")@ResponseBodypublic 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")@ResponseBodypublic 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 验证失败");// TODOreturn new CommonResult().failed();}} catch (AlipayApiException e) {e.printStackTrace();return "failure";}}@RequestMapping(value = "/notify_url")@ResponseBodypublic 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);// TODOreturn 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 {@AutowiredJdPayBean jdPayBean;private Logger log = LoggerFactory.getLogger(this.getClass());@RequestMapping("")@ResponseBodypublic 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")@ResponseBodypublic JdPayBean test() {return jdPayBean;}/*** App 支付** @return*/@RequestMapping(value = "/appPay", method = {RequestMethod.POST, RequestMethod.GET})@ResponseBodypublic 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 转化为 mapMap<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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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>");} elsesf.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("")@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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})@ResponseBodypublic 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";}
}

mallplus多商户商城 让支付触手可及,封装了微信支付、QQ支付、支付宝支付、京东支付、银联支付常用的支付方式以及各种常用的接口相关推荐

  1. 「开源系统」IJPay 让支付触手可及封装了微信支付宝等支付

    介绍语 本号主要是Java常用关键技术点,通用工具类的分享:以及springboot+springcloud+Mybatisplus+druid+mysql+redis+swagger+maven+d ...

  2. mallplus多商户商城全流程 操作文档

    下载地址 https://gitee.com/catshen/zscat_sw 用户端 http://www.yjlive.cn:8082/#/ 商户端 http://www.yjlive.cn:80 ...

  3. java跳转QQ支付宝_iApp跳转到QQ转账和微信支付界面,以及跳转个人QQ或者支付宝的AA支付...

    把下面的代码放入控件的点击事件中即可 不过要提醒大家记得更换成自己的支付连接哦! QQ转账 s qqpay="mqqapi://forward/url?url_prefix=aHR0cHM6 ...

  4. django手机访问_Django对接支付宝电脑网站、App支付步骤详解!这个框架是真强!...

    一.前言 本文主要针对 Python for Django 在对接支付宝电脑网站.手机网站.App支付过程中具体实现步骤进行详解: 相信大家支付功能也写了不少,但时间一长,再次用到的时候有些细节难免会 ...

  5. EasyPay(易支付)Android超简单微信支付宝支付接入

    今天我们来看看一个超简单集成微信和支付宝的支付框架EasyPay(易支付), 初学者都能一看就会一写就对的集成支付的方法. 首先还是先上gitHub链接 GitHub - kingofglory/Ea ...

  6. laravel银联支付

    一,安装&配置(网关支付的闭包) 在composer.json中添加如下依赖: "ignited/laravel-omnipay": "2.*", &q ...

  7. laravel5.2 银联支付

    一,安装&配置(网关支付的闭包) 在composer.json中添加如下依赖: "ignited/laravel-omnipay": "2.*", &q ...

  8. [Java实现银联支付 ]

    目录 前言: 以下是调用银联支付平台的API -demo: 注意: 依赖: 配置文件: 前言: 主要记录一些小笔记...... 以下是调用银联支付平台的API -demo: import com.un ...

  9. ios 支付宝、微信、银联支付集成

    一 .支付宝集成 支付宝官方集成文档 1.下载支付宝官方demo,将AlipaySDK.bundle.AlipaySDK.framework两个框架导入到项目中,如下图: 2.选择工程中 Build ...

  10. Android集成银联支付

    银联支付是继支付宝于微信支付之后的第三大支付方式,如果你已经看过前两篇博文,学会支付宝和微信的支付集成方法,接下来,银联支付就很简单了. 支付宝支付流程博文 http://blog.csdn.net/ ...

最新文章

  1. 禁止页面复制功能 js禁止复制 禁用页面右键菜单
  2. 分享Kali Linux 2017.1镜像
  3. Mysql 中,WEEK 与YEARWEEK函数的参数问题
  4. 牛客题霸 [ 孩子们的游戏] C++题解/答案
  5. 小程序·云开发实战 - 迷你微博
  6. “算法”的茧房,如何破局?
  7. Linux学习(lesson1)
  8. Pandas csv 文件,按条件删除行
  9. 电脑鼠标失控自己乱点_在这款沙盒游戏里,你只需要乱点鼠标就能成为建筑艺术家...
  10. 【sklearn第二十三讲】异常检测
  11. 烽火通信2018校招软件工程师编程题 - 题解
  12. 如何在html表格中添加超链接,excel怎么将工作表制作成网页 excel如何加入网页超链接...
  13. 为知笔记Typora编辑器上传图片失效(20.5.16)
  14. 一款好用的电池管理工具:App Tamer Mac版
  15. 使用python绘制标准心形线
  16. PS绘画效果滤镜Snap Art 4
  17. matlab基础总结与图像处理应用(上)
  18. 技术网站 常用的技术网站
  19. 100万并发连接服务器
  20. 关于声纹识别数据集VoxCeleb2下载问题--

热门文章

  1. 查看别人IP经典办法
  2. python编程入门第三版pdf-Python核心编程第3版PDF电子书免费下载
  3. 电脑连接上无线网却没有网,手机却能上网怎么解决
  4. Android源码学习
  5. 打造自己的Android源码学习环境之三:在虚拟机中安装Ubuntu(下)
  6. MapReduce:出租车数据案例
  7. Mysql客户端的安装
  8. 注意力稀缺的时代,写作软件如何选择?
  9. c语言书籍(c语言书籍)
  10. 秋招准备之——计算机操作系统