package org.springblade.modules.api.controller;

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.AlipayFundAuthOrderFreezeResponse;
import com.alipay.api.response.AlipayFundCouponOrderAgreementPayResponse;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.ijpay.alipay.AliPayApi;
import com.ijpay.alipay.AliPayApiConfig;
import com.ijpay.alipay.AliPayApiConfigKit;
import com.ijpay.core.kit.PayKit;
import com.ijpay.core.kit.RsaKit;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.utils.StringUtils;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.finance.controller.AbstractAliPayApiController;
import org.springblade.modules.finance.entity.Order;
import org.springblade.modules.finance.pay.entity.AjaxResult;
import org.springblade.modules.finance.pay.entity.AliPayBean;
import org.springblade.modules.finance.service.IOrderService;
import org.springblade.modules.shopping.entity.Consign;
import org.springblade.modules.shopping.service.IConsignService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>IJPay 让支付触手可及，封装了微信支付、支付宝支付、银联支付常用的支付方式以及各种常用的接口。</p>
 *
 * <p>不依赖任何第三方 mvc 框架，仅仅作为工具使用简单快速完成支付模块的开发，可轻松嵌入到任何系统里。 </p>
 *
 * <p>IJPay 交流群: 723992875</p>
 *
 * <p>Node.js 版: https://gitee.com/javen205/TNWX</p>
 *
 * <p>支付宝支付 Demo</p>
 *
 * @author Javen
 */
@RestController
@AllArgsConstructor
@RequestMapping(CommonConstant.API_URL + "/aliPay")
@Api(value = "支付宝接口", tags = "96.支付宝接口")
public class AliPay02Controller extends AbstractAliPayApiController {
	private static final Logger log = LoggerFactory.getLogger(AliPay02Controller.class);

	// 证书模式
	private final static String NOTIFY_URL = "/aliPay/cert_notify_url";
	private final static String RETURN_URL = "/aliPay/cert_return_url";

	// 普通公钥模式
    //private final static String NOTIFY_URL = "/api/v1/aliPay/notify_url";
	//private final static String RETURN_URL = "/api/v1/aliPay/return_url";

	private final AjaxResult result = new AjaxResult();

	@Autowired
	private AliPayBean aliPayBean;

	private final IOrderService orderService;
	private final IConsignService consignService;

	@Override
	public AliPayApiConfig getApiConfig() throws AlipayApiException {
		AliPayApiConfig aliPayApiConfig;
		try {
			aliPayApiConfig = AliPayApiConfigKit.getApiConfig(aliPayBean.getAppId());
		} catch (Exception e) {
			aliPayApiConfig = AliPayApiConfig.builder()
				.setAppId(aliPayBean.getAppId()) //aliPayBean.getAppId()
				.setAliPayPublicKey(aliPayBean.getPublicKey())
				.setAppCertPath(aliPayBean.getAppCertPath())
				.setAliPayCertPath(aliPayBean.getAliPayCertPath())
				.setAliPayRootCertPath(aliPayBean.getAliPayRootCertPath())
				.setCharset("UTF-8")
				.setPrivateKey(aliPayBean.getPrivateKey())
				.setServiceUrl(aliPayBean.getServerUrl())
				.setSignType("RSA2")
				// 普通公钥方式
				//.build();
				// 证书模式
				.buildByCert();
		}
		return aliPayApiConfig;
	}

	@PostMapping("/test")
	@ApiOperation(value = "获取阿里支付配置信息", notes = "获取阿里支付配置信息")
	@ApiOperationSupport(order = 2)
	public AliPayApiConfig test() {
		AliPayApiConfig aliPayApiConfig = AliPayApiConfigKit.getAliPayApiConfig();
		String charset = aliPayApiConfig.getCharset();
		log.info("charset>" + charset);
		return aliPayApiConfig;
	}

	/**
	 * app支付
	 */
	@GetMapping(value = "/appPay")
	@ApiOperationSupport(order = 3)
	@ApiOperation(value = "阿里支付", notes = "阿里支付")
	public AjaxResult appPay() {
		try {
			AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
			model.setBody("我是测试数据-By Javen");
			model.setSubject("App支付测试-By Javen");
			model.setOutTradeNo(StringUtils.getOutTradeNo());
			model.setTimeoutExpress("30m");
			model.setTotalAmount("0.01");
			model.setPassbackParams("zzy");
			model.setProductCode("123456512655");
			String orderInfo = AliPayApi.appPayToResponse(model, aliPayBean.getDomain() + NOTIFY_URL).getBody();
			result.success(orderInfo);
		} catch (AlipayApiException e) {
			e.printStackTrace();
			result.addError("system error:" + e.getMessage());
		}
		return result;
	}

	/**
	 * 创建订单
	 * {"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 = "/trade" , method = {RequestMethod.GET, RequestMethod.POST})
	@ResponseBody
	@ApiOperation(value = "创建订单", notes = "创建订单")
	@ApiOperationSupport(order = 4)
	public R tradeCreate(@ApiParam(value = "订单号", required = true) @RequestParam String outTradeNo,
						 @ApiParam(value = "支付渠道:aliPay支付宝，wechatPay微信支付，unionPay银联 ", required = true) @RequestParam String payFor) {

		Order order = orderService.getOne(Wrappers.<Order>lambdaQuery().eq(Order::getOutTradeNo, outTradeNo));
		if (order == null){
			return R.fail("请求参数错误！");
		}
		if(StringUtil.isEmpty(payFor)){
			return R.fail("请选择支付方式！");
		}
		if(order.getOrderType() == 3){
			//寄售订单而且寄售方式为寄售
			Consign consign = consignService.getOne(Wrappers.<Consign>lambdaQuery().eq(Consign::getConsignType,order.getOutTradeNo()));
			if (consign != null && consign.getConsignFor() == 2){
				return R.fail("该订单为寄售单，不能发起交易！");
			}
		}
		if("aliPay".equals(payFor)){
			String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
			AlipayTradeCreateModel model = new AlipayTradeCreateModel();
			model.setOutTradeNo(outTradeNo);
			model.setTotalAmount(order.getPayFee().toString());
			model.setBody("Body");
			model.setSubject("中宏酒业");
			//买家支付宝账号，和buyer_id不能同时为空
			//model.setBuyerLogonId("skuaqo5756@sandbox.com");
			try {
				AlipayTradeCreateResponse response = AliPayApi.tradeCreateToResponse(model, notifyUrl);
				return R.fail(response.getBody());
			} catch (AlipayApiException e) {
				e.printStackTrace();
				return R.fail("创建订单失败");
			}
		}
		return R.fail("创建订单失败");
	}

	@PostMapping(value = "/wapPayNoSdk")
	public void wapPayNoSdk(HttpServletResponse response) {
		try {
			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", aliPayBean.getDomain() + 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", aliPayBean.getDomain() + NOTIFY_URL);

			Map<String, String> bizMap = new HashMap<>();
			bizMap.put("body", "IJPay 聚合支付-H5");
			bizMap.put("subject", "IJPay 让支付触手可及");
			bizMap.put("out_trade_no", StringUtils.getOutTradeNo());
			bizMap.put("total_amount", "6.66");
			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());
			System.out.println(encrypt);
//            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();
		}
	}

	@PostMapping(value = "/wapPay")
	public void wapPay(HttpServletResponse response) {
		String body = "我是测试数据-By Javen";
		String subject = "Javen Wap支付测试";
		String totalAmount = "1";
		String passBackParams = "1";
		String returnUrl = aliPayBean.getDomain() + RETURN_URL;
		String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;

		AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
		model.setBody(body);
		model.setSubject(subject);
		model.setTotalAmount(totalAmount);
		model.setPassbackParams(passBackParams);
		String outTradeNo = StringUtils.getOutTradeNo();
		System.out.println("wap outTradeNo>" + outTradeNo);
		model.setOutTradeNo(outTradeNo);
		model.setProductCode("QUICK_WAP_PAY");

		try {
			AliPayApi.wapPay(response, model, returnUrl, notifyUrl);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * PC支付
	 */
	@PostMapping(value = "/pcPay")
	@ApiOperation(value = "PC支付", notes = "PC支付")
	public void pcPay(HttpServletResponse response) {
		try {
			String totalAmount = "88.88";
			String outTradeNo = StringUtils.getOutTradeNo();
			log.info("pc outTradeNo>" + outTradeNo);

			String returnUrl = aliPayBean.getDomain() + RETURN_URL;
			String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
			AlipayTradePagePayModel model = new AlipayTradePagePayModel();

			model.setOutTradeNo(outTradeNo);
			model.setProductCode("FAST_INSTANT_TRADE_PAY");
			model.setTotalAmount(totalAmount);
			model.setSubject("Javen PC支付测试");
			model.setBody("Javen IJPay 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);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	@PostMapping(value = "/tradePay")
	@ApiOperation(value = "支付宝声波/条形码支付测试", notes = "支付宝声波/条形码支付测试")
	public String tradePay(@RequestParam("authCode") 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 = aliPayBean.getDomain() + NOTIFY_URL;

		AlipayTradePayModel model = new AlipayTradePayModel();
		model.setAuthCode(authCode);
		model.setSubject(subject);
		model.setTotalAmount(totalAmount);
		model.setOutTradeNo(StringUtils.getOutTradeNo());
		model.setScene(scene);
		try {
			return AliPayApi.tradePayToResponse(model, notifyUrl).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	/**
	 * 扫码支付
	 */
	@GetMapping(value = "/tradePreCreatePay")
	@ApiOperation(value = "扫码支付", notes = "扫码支付")
	public String tradePreCreatePay() {
		String subject = "Javen 支付宝扫码支付测试";
		String totalAmount = "86";
		String storeId = "123";
//        String notifyUrl = aliPayBean.getDomain() + NOTIFY_URL;
		String notifyUrl = aliPayBean.getDomain() + "/aliPay/cert_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).getBody();
			JSONObject jsonObject = JSONObject.parseObject(resultStr);
			return jsonObject.getJSONObject("alipay_trade_precreate_response").getString("qr_code");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 单笔转账到支付宝账户
	 * https://docs.open.alipay.com/309/106235/
	 */
	@GetMapping(value = "/transfer")
	@ApiOperation(value = "单笔转账到支付宝账户", notes = "单笔转账到支付宝账户")
	public String transfer() {
		String totalAmount = "66";
		AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
		model.setOutBizNo(StringUtils.getOutTradeNo());
		model.setPayeeType("ALIPAY_LOGONID");
		model.setPayeeAccount("gxthqd7606@sandbox.com");
		model.setAmount(totalAmount);
		model.setPayerShowName("测试退款");
		model.setPayerRealName("沙箱环境");
		model.setRemark("javen测试单笔转账到支付宝");

		try {
			return AliPayApi.transferToResponse(model).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GetMapping(value = "/transferQuery")
	@ApiOperation(value = "查询转账信息", notes = "查询转账信息")
	public String transferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
								@RequestParam(required = false, name = "orderId") String orderId) {
		AlipayFundTransOrderQueryModel model = new AlipayFundTransOrderQueryModel();
		if (StringUtils.isNotEmpty(outBizNo)) {
			model.setOutBizNo(outBizNo);
		}
		if (StringUtils.isNotEmpty(orderId)) {
			model.setOrderId(orderId);
		}

		try {
			return AliPayApi.transferQueryToResponse(model).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GetMapping(value = "/uniTransfer")
	@ResponseBody
	@ApiOperation(value = "统一转账-转账至支付宝账户", notes = "统一转账-转账至支付宝账户")
	public String uniTransfer() {
		String totalAmount = "1";
		AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
		model.setOutBizNo(StringUtils.getOutTradeNo());
		model.setTransAmount(totalAmount);
		model.setProductCode("TRANS_ACCOUNT_NO_PWD");
		model.setBizScene("DIRECT_TRANSFER");
		model.setOrderTitle("统一转账-转账至支付宝账户");
		model.setRemark("IJPay 测试统一转账");

		Participant payeeInfo = new Participant();
		payeeInfo.setIdentity("gxthqd7606@sandbox.com");
		payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
		payeeInfo.setName("沙箱环境");
		model.setPayeeInfo(payeeInfo);

		try {
			return AliPayApi.uniTransferToResponse(model, null).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GetMapping(value = "/uniTransferQuery")
	@ResponseBody
	public String uniTransferQuery(@RequestParam(required = false, name = "outBizNo") String outBizNo,
								   @RequestParam(required = false, name = "orderId") String orderId) {
		AlipayFundTransCommonQueryModel model = new AlipayFundTransCommonQueryModel();
		if (StringUtils.isNotEmpty(outBizNo)) {
			model.setOutBizNo(outBizNo);
		}
		if (StringUtils.isNotEmpty(orderId)) {
			model.setOrderId(orderId);
		}

		try {
			return AliPayApi.transCommonQueryToResponse(model, null).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@GetMapping(value = "/accountQuery")
	@ResponseBody
	@ApiOperation(value = "账号查询", notes = "账号查询")
	public String accountQuery(@RequestParam(required = true, name = "aliPayUserId") String aliPayUserId) {
		AlipayFundAccountQueryModel model = new AlipayFundAccountQueryModel();
		model.setAlipayUserId(aliPayUserId);
		model.setAccountType("ACCTRANS_ACCOUNT");
		try {
			return AliPayApi.accountQueryToResponse(model, null).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 资金授权冻结接口
	 */
	@GetMapping(value = "/authOrderFreeze")
	@ResponseBody
	@ApiOperation(value = "资金授权冻结接口", notes = "资金授权冻结接口")
	public AlipayFundAuthOrderFreezeResponse 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 IJPay");
			model.setAmount("36");
			model.setProductCode("PRE_AUTH");

			return AliPayApi.authOrderFreezeToResponse(model);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
	 * 红包协议支付接口
	 * https://docs.open.alipay.com/301/106168/
	 */
	@GetMapping(value = "/agreementPay")
	@ResponseBody
	@ApiOperation(value = "红包协议支付接口", notes = "红包协议支付接口")
	public AlipayFundCouponOrderAgreementPayResponse agreementPay() {
		try {
			AlipayFundCouponOrderAgreementPayModel model = new AlipayFundCouponOrderAgreementPayModel();
			model.setOutOrderNo(StringUtils.getOutTradeNo());
			model.setOutRequestNo(StringUtils.getOutTradeNo());
			model.setOrderTitle("红包协议支付接口-By IJPay");
			model.setAmount("36");
			model.setPayerUserId("2088102180432465");

			return AliPayApi.fundCouponOrderAgreementPayToResponse(model);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 下载对账单
	 */
	@GetMapping(value = "/dataDataServiceBill")
	@ResponseBody
	@ApiOperation(value = "下载对账单", notes = "下载对账单")
	public String dataDataServiceBill(@RequestParam("billDate") String billDate) {
		try {
			AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel();
			model.setBillType("trade");
			model.setBillDate(billDate);
			return AliPayApi.billDownloadUrlQuery(model);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 退款
	 */
	@PostMapping(value = "/tradeRefund")
	@ResponseBody
	@ApiOperation(value = "退款", notes = "退款")
	public String tradeRefund(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {

		try {
			AlipayTradeRefundModel model = new AlipayTradeRefundModel();
			if (StringUtils.isNotEmpty(outTradeNo)) {
				model.setOutTradeNo(outTradeNo);
			}
			if (StringUtils.isNotEmpty(tradeNo)) {
				model.setTradeNo(tradeNo);
			}
			model.setRefundAmount("86.00");
			model.setRefundReason("正常退款");
			return AliPayApi.tradeRefundToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 交易查询
	 */
	@PostMapping(value = "/tradeQuery")
	@ResponseBody
	@ApiOperation(value = "交易查询", notes = "交易查询")
	public String tradeQuery(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
		try {
			AlipayTradeQueryModel model = new AlipayTradeQueryModel();
			if (StringUtils.isNotEmpty(outTradeNo)) {
				model.setOutTradeNo(outTradeNo);
			}
			if (StringUtils.isNotEmpty(tradeNo)) {
				model.setTradeNo(tradeNo);
			}
			return AliPayApi.tradeQueryToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	@PostMapping(value = "/tradeQueryByStr")
	@ResponseBody
	@ApiOperation(value = "交易查询", notes = "交易查询")
	public String tradeQueryByStr(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
		AlipayTradeQueryModel model = new AlipayTradeQueryModel();
		if (StringUtils.isNotEmpty(outTradeNo)) {
			model.setOutTradeNo(outTradeNo);
		}
		if (StringUtils.isNotEmpty(tradeNo)) {
			model.setTradeNo(tradeNo);
		}

		try {
			return AliPayApi.tradeQueryToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}

		return null;
	}



	/**
	 * 撤销订单
	 */
	@PostMapping(value = "/tradeCancel")
	@ResponseBody
	@ApiOperation(value = "撤销订单", notes = "撤销订单")
	public String tradeCancel(@RequestParam(required = false, name = "outTradeNo") String outTradeNo, @RequestParam(required = false, name = "tradeNo") String tradeNo) {
		try {
			AlipayTradeCancelModel model = new AlipayTradeCancelModel();
			if (StringUtils.isNotEmpty(outTradeNo)) {
				model.setOutTradeNo(outTradeNo);
			}
			if (StringUtils.isNotEmpty(tradeNo)) {
				model.setTradeNo(tradeNo);
			}

			return AliPayApi.tradeCancelToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 关闭订单
	 */
	@ApiOperation(value = "关闭订单", notes = "关闭订单")
	@RequestMapping(value = "/tradeClose")
	@ResponseBody
	public String tradeClose(@RequestParam("outTradeNo") String outTradeNo, @RequestParam("tradeNo") String tradeNo) {
		try {
			AlipayTradeCloseModel model = new AlipayTradeCloseModel();
			if (StringUtils.isNotEmpty(outTradeNo)) {
				model.setOutTradeNo(outTradeNo);
			}
			if (StringUtils.isNotEmpty(tradeNo)) {
				model.setTradeNo(tradeNo);
			}

			return AliPayApi.tradeCloseToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 结算
	 */
	@ApiOperation(value = "结算", notes = "结算")
	@RequestMapping(value = "/tradeOrderSettle")
	@ResponseBody
	public String tradeOrderSettle(@RequestParam("tradeNo") String tradeNo) {
		try {
			AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel();
			model.setOutRequestNo(StringUtils.getOutTradeNo());
			model.setTradeNo(tradeNo);

			return AliPayApi.tradeOrderSettleToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 获取应用授权URL并授权
	 */
	@ApiOperation(value = "获取应用授权URL并授权", notes = "获取应用授权URL并授权")
	@PostMapping(value = "/toOauth")
	@ResponseBody
	public void toOauth(HttpServletResponse response) {
		try {
			String redirectUri = aliPayBean.getDomain() + "/aliPay/redirect_uri";
			String oauth2Url = AliPayApi.getOauth2Url(aliPayBean.getAppId(), redirectUri);
			response.sendRedirect(oauth2Url);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 应用授权回调
	 */
	@RequestMapping(value = "/redirect_uri")
	@ResponseBody
	@ApiOperation(value = "应用授权回调", notes = "应用授权回调")
	public String redirectUri(@RequestParam("app_id") String appId, @RequestParam("app_auth_code") String appAuthCode) {
		try {
			System.out.println("app_id:" + appId);
			System.out.println("app_auth_code:" + appAuthCode);
			//使用app_auth_code换取app_auth_token
			AlipayOpenAuthTokenAppModel model = new AlipayOpenAuthTokenAppModel();
			model.setGrantType("authorization_code");
			model.setCode(appAuthCode);
			return AliPayApi.openAuthTokenAppToResponse(model).getBody();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 查询授权信息
	 */
	@GetMapping(value = "/openAuthTokenAppQuery")
	@ResponseBody
	@ApiOperation(value = "查询授权信息", notes = "查询授权信息")
	public String openAuthTokenAppQuery(@RequestParam("appAuthToken") String appAuthToken) {
		try {
			AlipayOpenAuthTokenAppQueryModel model = new AlipayOpenAuthTokenAppQueryModel();
			model.setAppAuthToken(appAuthToken);
			return AliPayApi.openAuthTokenAppQueryToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 批量付款到支付宝账户有密接口
	 */
	@PostMapping(value = "/batchTrans")
	@ResponseBody
	@ApiOperation(value = "批量付款到支付宝账户有密接口", notes = "批量付款到支付宝账户有密接口")
	public void batchTrans(HttpServletResponse response) {
		try {
			String signType = "MD5";
			String notifyUrl = aliPayBean.getDomain() + 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, aliPayBean.getPrivateKey(), signType, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 地铁购票核销码发码
	 */
	@ApiOperation(value = "地铁购票核销码发码", notes = "地铁购票核销码发码")
	@PostMapping(value = "/voucherGenerate")
	@ResponseBody
	public String voucherGenerate(@RequestParam("tradeNo") String tradeNo) {
		try {
			//需要支付成功的订单号
//			String tradeNo = getPara("tradeNo");

			AlipayCommerceCityfacilitatorVoucherGenerateModel model = new AlipayCommerceCityfacilitatorVoucherGenerateModel();
			model.setCityCode("440300");
			model.setTradeNo(tradeNo);
			model.setTotalFee("8");
			model.setTicketNum("2");
			model.setTicketType("oneway");
			model.setSiteBegin("001");
			model.setSiteEnd("002");
			model.setTicketPrice("4");
			return AliPayApi.voucherGenerateToResponse(model).getBody();
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	@RequestMapping(value = "/return_url")
	@ResponseBody
	@ApiOperation(value = "支付回调", notes = "支付回调")
	public String returnUrl(HttpServletRequest request) {
		try {
			// 获取支付宝GET过来反馈信息
			Map<String, String> map = AliPayApi.toMap(request);
			for (Map.Entry<String, String> entry : map.entrySet()) {
				System.out.println(entry.getKey() + " = " + entry.getValue());
			}

			boolean verifyResult = AlipaySignature.rsaCheckV1(map, aliPayBean.getPublicKey(), "UTF-8",
				"RSA2");

			if (verifyResult) {
				// TODO 请在这里加上商户的业务逻辑程序代码
				System.out.println("return_url 验证成功");

				return "success";
			} else {
				System.out.println("return_url 验证失败");
				// TODO
				return "failure";
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return "failure";
		}
	}

	@RequestMapping(value = "/cert_return_url")
	@ResponseBody
	@ApiOperation(value = "支付回调（证书）", notes = "支付回调（证书）")
	public String certReturnUrl(HttpServletRequest request) {
		try {
			// 获取支付宝GET过来反馈信息
			Map<String, String> map = AliPayApi.toMap(request);
			for (Map.Entry<String, String> entry : map.entrySet()) {
				System.out.println(entry.getKey() + " = " + entry.getValue());
			}

			boolean verifyResult = AlipaySignature.rsaCertCheckV1(map, aliPayBean.getAliPayCertPath(), "UTF-8",
				"RSA2");

			if (verifyResult) {
				// TODO 请在这里加上商户的业务逻辑程序代码
				System.out.println("certReturnUrl 验证成功");

				return "success";
			} else {
				System.out.println("certReturnUrl 验证失败");
				// TODO
				return "failure";
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return "failure";
		}
	}


	@RequestMapping(value = "/notify_url")
	@ResponseBody
	@ApiOperation(value = "验证支付回调", notes = "验证支付回调")
	public String notifyUrl(HttpServletRequest request) {
		try {
			// 获取支付宝POST过来反馈信息
			Map<String, String> params = AliPayApi.toMap(request);

			for (Map.Entry<String, String> entry : params.entrySet()) {
				System.out.println(entry.getKey() + " = " + entry.getValue());
			}

			boolean verifyResult = AlipaySignature.rsaCheckV1(params, aliPayBean.getPublicKey(), "UTF-8", "RSA2");

			if (verifyResult) {
				// TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
				System.out.println("notify_url 验证成功succcess");
				return "success";
			} else {
				System.out.println("notify_url 验证失败");
				// TODO
				return "failure";
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return "failure";
		}
	}

	@RequestMapping(value = "/cert_notify_url")
	@ResponseBody
	@ApiOperation(value = "验证支付回调（证书）", notes = "验证支付回调（证书）")
	public String certNotifyUrl(HttpServletRequest request) {
		try {
			// 获取支付宝POST过来反馈信息
			Map<String, String> params = AliPayApi.toMap(request);

			for (Map.Entry<String, String> entry : params.entrySet()) {
				System.out.println(entry.getKey() + " = " + entry.getValue());
			}

			boolean verifyResult = AlipaySignature.rsaCertCheckV1(params, aliPayBean.getAliPayCertPath(), "UTF-8", "RSA2");

			if (verifyResult) {
				// TODO 请在这里加上商户的业务逻辑程序代码 异步通知可能出现订单重复通知 需要做去重处理
				System.out.println("certNotifyUrl 验证成功succcess");
				return "success";
			} else {
				System.out.println("certNotifyUrl 验证失败");
				// TODO
				return "failure";
			}
		} catch (AlipayApiException e) {
			e.printStackTrace();
			return "failure";
		}
	}

}
