支付宝支付
支付宝
调用支付宝预下单接口
package com.sunxing.service.merchants.utils.pay;
import com.alipay.api.*;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author vincen
*/
@Component
public class AliPayHelper {
/**
* log
*/
private static final Logger log = LoggerFactory.getLogger(AliPayHelper.class);
/**
*
*/
private static final AlipayClient ALI_PAY_CLIENT = new DefaultAlipayClient(AliConstant.REQUEST_URL, AliConstant.APP_ID, AliConstant.PRIVATE_KEY, AliConstant.FORMAT, AliConstant.CHARSET, AliConstant.ALI_PAY_PUBLIC_KEY, AliConstant.SIGN_TYPE);
/**
* 当面付2.0生成支付二维码
* @param outTradeNo
* @param totalAmount
* @param subject
* @return
*/
public AlipayTradePrecreateResponse tradePrecreate(String outTradeNo, String totalAmount, String subject) {
//创建API对应的request类
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
Map<String, String> map = new HashMap();
map.put("out_trade_no", outTradeNo);
map.put("total_amount", totalAmount);
map.put("subject", subject);
map.put("store_id", AliConstant.APP_ID);
map.put("timeout_express", AliConstant.TIME_OUT_EXPRESS);
map.put("qr_code_timeout_express", AliConstant.QR_CODE_TIME_OUT_EXPRESS);
request.setNotifyUrl(AliConstant.AUTH_CALLBACK_URL + "/api/v1/pay/notify/trade/result");
String bizContent = toJson(map);
System.out.println(bizContent);
request.setBizContent(bizContent);
AlipayTradePrecreateResponse response = null;
log.error("生成当面付入参:" + bizContent);
try {
response = ALI_PAY_CLIENT.execute(request);
} catch (AlipayApiException e) {
log.error("预下单接口异常:" + e);
}
return response;
}
/**
*
* @param outTradeNo
* @return
*/
public AlipayTradeQueryResponse queryTradeResult(String outTradeNo) {
//创建API对应的request类
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
Map<String, String> map = new HashMap();
map.put("out_trade_no", outTradeNo);
String bizContent = toJson(map);
request.setBizContent(bizContent); //设置业务参数
AlipayTradeQueryResponse response = null;//通过alipayClient调用API,获得对应的response类
try {
response = ALI_PAY_CLIENT.execute(request);
} catch (AlipayApiException e) {
log.error("查询下单状态接口异常:" + e);
}
return response;
}
/**
*
* @param map
* @return
*/
private String toJson(Map map) {
ObjectMapper objectMapper = new ObjectMapper();
String bizContent = "";
try {
bizContent = objectMapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
log.error("json转换错误:" + e);
}
return bizContent;
}
}
package com.sunxing.service.merchants.utils.pay;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* @author vincen
*/
@Configuration
public class AliConstant {
public static String AUTH_CALLBACK_URL;
public static final String OAUTH_2_URL = "https://openauth.alipay.com/oauth2/publicAppAuthorize.htm";
public static final String APP_ID="XXXXX";
public static final String REQUEST_URL="https://openapi.alipay.com/gateway.do";
public static String SELLER_ID;
public static String TIME_OUT_EXPRESS;
public static String QR_CODE_TIME_OUT_EXPRESS;
public static final String FORMAT = "json";
public static final String CHARSET = "UTF-8";
public static final String SIGN_TYPE = "RSA2";
@Value("${config.ali.payment.callback}")
public void setAuthCallbackUrl(String authCallbackUrl) {
AUTH_CALLBACK_URL = authCallbackUrl;
}
@Value("${config.ali.payment.sellerId}")
public void setSellerId(String sellerId) {
SELLER_ID = sellerId;
}
@Value("${config.ali.payment.timeoutExpress}")
public void setTimeOutExpress(String timeOutExpress) {
TIME_OUT_EXPRESS = timeOutExpress;
}
@Value("${config.ali.payment.qrCodeTimeoutExpress}")
public void setQrCodeTimeOutExpress(String qrCodeTimeOutExpress) {
QR_CODE_TIME_OUT_EXPRESS = qrCodeTimeOutExpress;
}
public static final String PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5+p4gE9+KYfUP" +
"FOrEaobBW+I0UHgjIE8uMLcivBoHUdQJJrX+PSLFeeQ192Z7vFhcP4+ooEkmtIdI" +
"sJdS+q87Pfyj2wc3U06mxAR3sE4OZseHndoRCd0lalIoRR5IYPQrQCchfy5cLkpP" +
"nIAlpuclq4EeWdl0ANUnQyIa72TUTtQUb9OCJwcqcxHas1TXfTnWFhr1gpqDOE3m" +
"Aao2b6dwb9byHkBna6ejy6lYDsjCQjwr5X31QkYklL87EpB/VwKbsOdUsqhrlJ+j" +
"TGg8OI4hNvC0C3uEVgrGHJoShNf4NgaM2+anluCVq8dgZw0qMzD3gKnBULLeUC5Q" +
"LT+aUINdAgMBAAECggEAPs+r0/2iQ+RtlZhk6c1okalsrmp3CLYCyADf+TU6PTqf" +
"uC+Ay8ruEW/naWqTDDtCRHWbGUJ5Mj9KaXxqvzW3NPTsfJKez0qth5kwQRQkaKzB" +
"usXPPm3saJSOBtfBMIS+MlVKYf/IMo3XvyeGCDFkY86Wnx+NV6ZoVwhPXnV3wlQB" +
"3F2nG7LsZUPm9SdtLbWblKOOHziOEU5rhte52IRqHSYYT04UxIorLDbYdbsGGfhT" +
"2Af0iDbLgK/lm0M+y2zilFfWFI3gVq342uG5E/mRhTPBAZ1jczWjMz4KjdcYue3v" +
"SFyQNYnc63Ku99AQtydYTRjgVmM6c1lohkSZktSZaQKBgQDbvtIVVQc+P6vOph1X" +
"fqhsurSRXNcbnphQE6A4RHpZ448PrIdz8KOwDhqVdJ6ooY8b6x0L7ZLyL5r+EDpY" +
"N3B7wnIBymoTE//KSR27hxr1TiPuatiANc1ieMwj9c4oiHdIJA/GCKeJ6AYz34wy" +
"2esFJApaxXGpuMT0lOlWBtjsBwKBgQDYqaL6DIfyRk6+Oz5Q7quQuuKO3IfnbWvF" +
"94n8u7vzqkDIInhs/eIh70f1dqG+xwknyjYnOD8Si81WihGKNMBEQtCHntM5qgrz" +
"LrX/D3AdMvbPDmS51jZrRSJogxN15VEJ4paYAMgf9NP5TQEnKqVOZysdDP5qeo4S" +
"ewPipKEEewKBgEgtNyfWk9h4ZWAs47pXWc7MzH5qdiUWRIUYzSluJJndyqGlU6Bb" +
"TAiJuWWZtntBBZZv9Uxzri5qQIhuoBtVqlacGYJJD+pQSVYSCfgMemhUUC0BXzdN" +
"dLaBYtv04tAhcrx5S80KDq2XTXXmI/bPdO6Ij5u4TxEVJj5B1JxBKDkUCFAoGBAItm" +
"KZvkMBurLMKsb123Ed+evmHYdgBqoGrQ55EaYMVXhzK9KupFNxdKUuwVld+fQ768" +
"FbeKMtqF5GmHj91yLzo8GtsHTzPMuhrYtPQURLgksDNsOVZwArdl1cuUehLipg9M" +
"IERQTHJzHWdLKjC++XjGXDDmyVJM49f0Gf3amla9AoGAJ4dl96QjWuVxTqOwNMr0" +
"1vtlJq7KX1clzEpeimA7Cx35rtSUn1oxZ+YiYgBRFDfgMtHHAcEm2hk2AlKC3N9k" +
"pNDfvZyyErowOEDwqsLejiw3smrrAA/JovOIaq6tXlSoL2RZxja3JBb70CPd20Tp" +
"o9FcDvExzaR5Ml6h71n/6Dk=XXXXX";
public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAufqeIBPfimH1DxTqxGqG" +
"wVviNFB4IyBPLjC3IrwaB1HUCSa1/j0ixXnkNfdme7xYXD+PqKBJJrSHSLCXUvqv" +
"Oz38o9sHN1NOpsQEd7BODmbHh5XX3aEQndJWpSKEUeSGD0K0AnIX8uXC5KT5yAJabn" +
"JauBHlnZdADVJ0MiGu9k1E7UFG/TgicHKnMR2rNU13051hYa9YKagzhN5gGqNm+n" +
"cG/W8h5AZ2uno8upWA7IwkI8K+V99UJGJJS/OxKQf1cCm7DnVLKoa5Sfo0xoPDiO" +
"ITbwtAt7hFYKxhyaEoTX+DYGjNvmp5bglavHYGcNKjMw94CpwVCy3lAuUC0/mlCD" +
"XQIDAQAB";
public static final String ALI_PAY_PUBLIC_KEY = "MIIBIXXjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCXXAQEAsv1nQVBYI4j2GxoZ/LaXplXyH67H1GoPq+GVv0V0DGroaP0oUvHVuf2gK5j4f0LFfBeDGB0S5ISghgjDdJJdKM9o+Xd33z8XvIZbwpw42UdAn/oV/GLZXd7tp1AXqMY4/YKEj/RpfK68a9LPC3U2ucHDKCkMnzN1Y4F19ek504CDCsP5PhJp1tgRF/8cszwysCgTRE9GSzFXsH5BCIa1qDJRbODsAWi1ROnKRb+DB8ky5DmVHd25P9u0TYM6v3qdqasrsTkjrHa3KM9s033m/1oaU5JaoKXzcDGM2fQXmDNlyA5WycJyvhPmsrzilN0ElX7SLSxcdSP/t1qIolkxRwIDAQAB";
public static class AppPay {
public static final String PRODUCT_CODE = "QUICK_MSECURITY_PAY";
public static final String TIMEOUT = "30m";
}
public static class WebPay {
public static final String PRODUCT_CODE = "QUICK_WAP_WAY";
public static final String TIMEOUT = "10m";
}
public static class Transfer {
public static final String PAYEE_TYPE_LOGON_ID = "ALIPAY_LOGONID";
public static final String PAYEE_TYPE_USER_ID = "ALIPAY_USERID";
}
}
//调用支付宝预下单接口
MerchantsReceiptRecord entity = getReceiptRecordDTOConvertEntity(request, CurrentUserHolder.getCreateBy(), query.getClaimUuid());
AlipayTradePrecreateResponse payResult = aliPayHelper.tradePrecreate(entity.getReceiptOrder(), StringUtils.isEmpty(price) ? request.getAmount() : price, "收款");
if (payResult != null && payResult.isSuccess()) {
Integer result = merchantsReceiptRecordMapper.save(entity);
if (result <= 0) {
return AppResult.error("添加收款失败");
}
PayResultVO response = new PayResultVO();
response.setOutTradeNo(payResult.getOutTradeNo());
response.setQrCode(payResult.getQrCode());
RedisUtils.setKey(alipaykey + CurrentUserHolder.getUserUuid() + ":" + response.getQrCode(), "1", 290);
return AppResult.ok(response);
} else {
logger.info("=============================支付宝已下单失败============================,contactUuid {},contactPrice {},error {}",request.getContactUuid(),request.getAmount(),payResult.getMsg());
return AppResult.error("支付宝已下单失败:" + payResult.getMsg());
}
回调
/**
* 支付回调CallBack
* 收款状态(1.待付款 2.已付款 3.付款失败 4.订单关闭)
*
* @param request
* @param response
*/
@PostMapping("/notify/trade/result")
public AppResult getTradeResult(HttpServletRequest request, HttpServletResponse response) {
try {
logger.info("=============================回调进来啦Start============================");
MerchantsReceiptRecord entity = new MerchantsReceiptRecord();
Map<String, String> requestParams = requestParamToMap(request);
//签名检查成功
Boolean check = checkSignature(requestParams);
if (check) {
//交易状态
String tradeStatus = requestParams.get("trade_status");
//收款订单号
String outTradeNo = requestParams.get("out_trade_no");
//alipay付款流水号
String tradeNo = requestParams.get("trade_no");
logger.info("============================回调效验正常参数============================,tradeStatus:{},outTradeNo:{},tradeNo{}", tradeStatus, outTradeNo, tradeNo);
MerchantsReceiptRecord merchantsReceiptRecord = merchantsReceiptRecordMapper.getReceiptRecordByReceiptOrder(outTradeNo);
if (merchantsReceiptRecord != null && merchantsReceiptRecord.getReceiptType().equals(ReceiptType.RT1.getValue())) {
if (Code.TradeStatus.TRADE_SUCCESS.code.equals(tradeStatus) || Code.TradeStatus.TRADE_FINISHED.code.equals(tradeStatus)) {
logger.info("=============================回调支付成功,支付成功:=============================");
entity.setReceiptType(ReceiptType.RT2.getValue());
} else if (Code.TradeStatus.TRADE_CLOSED.code.equals(tradeStatus)) {
logger.info("=============================回调支付失败,订单关闭:============================={}", response);
entity.setReceiptType(ReceiptType.RT4.getValue());
} else {
logger.info("=============================回调支付失败,付款失败:============================= {}", response);
entity.setReceiptType(ReceiptType.RT3.getValue());
}
entity.setReceiptOrder(outTradeNo);
entity.setPaySerialNumber(tradeNo);
entity.setReceiptDate(new Date());
entity.setModifyTime(new Date());
entity.setModifyBy("回调");
merchantsReceiptRecordMapper.update(entity);
//支付回调成功验证收款分期和非分期合同支付状态
if (entity.getReceiptType().equals(ReceiptType.RT2.getValue())) {
MerchantContactDTO queryContract = merchantsContractMapper.getMerchantContactByContactUuid(merchantsReceiptRecord.getContractUuid());
if (queryContract != null) {
if (queryContract.getIsStaging().equals(StagingType.ST0.getValue())) {
//全额付款
logger.info("=============================全部付款 全部付款=============================,contractUuid {}", queryContract.getContractUuid());
updateContactPaymentStatus(queryContract.getContractUuid(), PaymentStatus.PS2);
} else {
//分期付款
logger.info("=============================分期付款 回调分期付款=============================,contractUuid {}", queryContract.getContractUuid());
BigDecimal paid = merchantsReceiptRecordMapper.getReceiptRecordByPaid(merchantsReceiptRecord.getContractUuid());
if (paid != null) {
logger.info("=============================分期付款 回调分期付款已支付金额=============================,contractUuid {},paidPrice {},contactAmount {}", queryContract.getContractUuid(), paid, queryContract.getContactAmount());
if (paid.compareTo(queryContract.getContactAmount()) == 0) {
//全部付款
updateContactPaymentStatus(queryContract.getContractUuid(), PaymentStatus.PS2);
logger.info("=============================分期付款 全部付款=============================,contractUuid {}", queryContract.getContractUuid());
} else {
//部分付款
updateContactPaymentStatus(queryContract.getContractUuid(), PaymentStatus.PS1);
logger.info("=============================分期付款 部分付款=============================,contractUuid {}", queryContract.getContractUuid());
}
} else {
//未付款
//updateContactPaymentStatus(queryContract, PaymentStatus.PS0);
logger.info("=============================分期付款 已支付金额为null=============================,contractUuid {}", queryContract.getContractUuid());
}
}
} else {
logger.info("=============================回调合同不存在=============================,contractUuid {}", merchantsReceiptRecord.getContractUuid());
return AppResult.error("合同不存在");
}
} else {
logger.info("=============================回调状态不是已付款=============================,contractUuid {},支付状态为 {}", merchantsReceiptRecord.getContractUuid(), entity.getReceiptType());
return AppResult.error("回调状态不是已付款");
}
} else {
if (merchantsReceiptRecord != null && merchantsReceiptRecord.getReceiptType() != null) {
logger.info("=============================回调状态已变更,支付订单状态已变更=============================,收款状态{}:", ReceiptType.getEnumByKey(merchantsReceiptRecord.getReceiptType()).getDescription());
return AppResult.error("回调状态已变更,支付订单状态已变更,收款状态{}:", ReceiptType.getEnumByKey(merchantsReceiptRecord.getReceiptType()).getDescription());
} else {
logger.info("=============================回调收款订单不存在=============================");
return AppResult.error("收款订单不存在");
}
}
} else {
logger.info("=============================回调支付失败,没进check:============================= {}", response);
return AppResult.error("支付失败,没进check:" + response);
}
} catch (Exception e) {
logger.info("=============================回调异常============================{}", e);
} finally {
logger.info("=============================回调结束End============================");
}
return AppResult.ok();
}
小蚊子大人