Authored by tanling

海关

... ... @@ -12,6 +12,7 @@ import com.yohobuy.ufo.model.order.bo.PaymentData;
import com.yohoufo.order.service.pay.alipay.AlipayCrossBorderService;
import com.yohoufo.order.service.pay.alipay.AbstractAlipayService;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryCustomsResponse;
import com.yohoufo.order.service.pay.unionpay.JsUnionpayService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
... ... @@ -121,19 +122,16 @@ public class PaymentController {
}
/**
* 跨境支付宝推送支付单
* 查询海关清关情况
* @param orderCode
* @param outRequestNo
* @param tradeNo
* @param amount
* @return
*/
@RequestMapping(params = "/erp/order/customes")
public ApiResponse customs(@RequestParam(name = "orderCode") long orderCode,
@RequestParam(name = "tradeNo") String tradeNo,
@RequestParam(name = "amount") double amount){
AlipayCustomsResponse alipayCustomsResponse = paymentService.customs(orderCode, tradeNo, amount);
return new ApiResponse.ApiResponseBuilder().code(PrepayResponse.SUCCESS).data(alipayCustomsResponse).message("推送支付单").build();
@RequestMapping(params = "/erp/order/queryCustoms")
public ApiResponse queryCustoms(@RequestParam(name = "orderCode") long orderCode){
AlipayQueryCustomsResponse alipayCustomsResponse = paymentService.queryCustoms(orderCode);
return new ApiResponse.ApiResponseBuilder().code(PrepayResponse.SUCCESS).data(alipayCustomsResponse).message("查询海关清关情况").build();
}
... ...
... ... @@ -13,6 +13,7 @@ import com.yohobuy.ufo.model.order.constants.OrderConstant;
import com.yohobuy.ufo.model.order.constants.SkupType;
import com.yohobuy.ufo.model.order.req.SellerDeliverToDepotReq;
import com.yohoufo.common.alarm.EventBusPublisher;
import com.yohoufo.common.exception.UfoServiceException;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.common.utils.StringUtil;
import com.yohoufo.dal.order.BuyerOrderGoodsMapper;
... ... @@ -20,7 +21,9 @@ import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.BuyerOrderMetaMapper;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.*;
import com.yohoufo.dal.user.model.ZhiMaCert;
import com.yohoufo.order.constants.ClearanceFailType;
import com.yohoufo.order.constants.ClientSpecialSemanticCode;
import com.yohoufo.order.constants.MetaKey;
import com.yohoufo.order.event.DeliverNoticeEvent;
import com.yohoufo.order.event.ErpBuyerOrderEvent;
... ... @@ -38,6 +41,7 @@ import com.yohoufo.order.service.pay.alipay.AlipayCrossBorderService;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.CustomsErrorMsg;
import com.yohoufo.order.service.proxy.*;
import com.yohoufo.order.service.support.CustomsSupportService;
import com.yohoufo.order.utils.BuyerOrderUtils;
import com.yohoufo.order.utils.SellerGoodsHelper;
import com.yohoufo.order.utils.TimeUtils;
... ... @@ -122,6 +126,13 @@ public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
BuyerOrderCancelService buyerOrderCancelService;
@Autowired
private UserProxyService userProxyService;
@Autowired
CustomsSupportService customsSupportService;
private ExecutorService executors = Executors.newFixedThreadPool(1);
... ... @@ -460,25 +471,8 @@ public class BuyerOrderPaymentService extends AbstractOrderPaymentService {
case OVERSEAS_IN_STOCK:
processOverSeasOrder(buyerOrder, sellerOrderGoods);
// 跨境支付 推送支付单
if (buyerOrder.getPayment() == Payment.CROSS_BORDER_ALIPAY.getCode() && orderInfo.getPaymentData()!=null){
String tradeNo = orderInfo.getPaymentData().getTradeNo();
try{
AlipayCustomsResponse alipayCustomsResponse = crossBorderService.customsOpenApi(buyerOrder.getOrderCode(),
tradeNo, buyerOrder.getAmount().doubleValue());
if ("F".equalsIgnoreCase(alipayCustomsResponse.getIs_success())){
String error = StringUtils.isEmpty(alipayCustomsResponse.getResult_code()) ? alipayCustomsResponse.getError() : alipayCustomsResponse.getResult_code();
buyerOrderCancelService.clearanceFail(buyerOrder.getOrderCode(),
CustomsErrorMsg.getCustomsError(error),
ClearanceFailType.BUYER);
logger.warn("customs error. {},{},{}",buyerOrder.getOrderCode(), tradeNo, buyerOrder.getAmount().doubleValue());
}
}catch (Exception e){
logger.warn("customs error. {},{},{},{},{}",buyerOrder.getOrderCode(), tradeNo, buyerOrder.getAmount().doubleValue(),e);
}
}
// 推送支付单到海关
customsSupportService.sendPaymentInfoToCustoms(orderCode, uid);
break;
... ...
... ... @@ -12,18 +12,18 @@ import com.yohoufo.order.model.response.PaymentConfirmRsp;
import com.yohoufo.order.model.response.PrepayResponse;
import com.yohoufo.order.service.pay.AbstractPayService;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryCustomsResponse;
public interface IPaymentService {
/**
* 推送支付单
* 海关清关状态查询
* @param orderCode
* @param tradeNo
* @param amount
* @return
*/
public AlipayCustomsResponse customs(long orderCode, String tradeNo, double amount);
public AlipayQueryCustomsResponse queryCustoms(long orderCode);
/**
* 获取订单信息(买家订单|卖家订单|入驻充值)
... ...
... ... @@ -51,12 +51,14 @@ import com.yohoufo.order.service.pay.AbstractPayService;
import com.yohoufo.order.service.pay.alipay.AlipayCrossBorderService;
import com.yohoufo.order.service.pay.alipay.AlipayOuyinService;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.CustomsErrorMsg;
import com.yohoufo.order.service.pay.unionpay.JsUnionpayService;
import com.yohoufo.order.service.pay.wallet.WalletPayService;
import com.yohoufo.order.service.pay.weixin.WeixinMiniappPayService;
import com.yohoufo.order.service.pay.weixin.WeixinPayUFORealAppService;
import com.yohoufo.order.service.proxy.WalletTransferService;
import com.yohoufo.order.service.support.CustomsSupportService;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import com.yohoufo.order.service.transfer.TransferResult;
... ... @@ -187,29 +189,24 @@ public class PaymentServiceImpl implements IPaymentService {
@Autowired
private AlipayCrossBorderService crossBorderService;
@Autowired
BuyerOrderCancelService buyerOrderCancelService;
/**
* 推送支付单
* 海关清关状态查询
* @param orderCode
* @param tradeNo
* @param amount
* @return
*/
public AlipayCustomsResponse customs(long orderCode, String tradeNo, double amount){
public AlipayQueryCustomsResponse queryCustoms(long orderCode){
if (orderCode<0
|| StringUtils.isEmpty(tradeNo)
|| amount < 0){
logger.warn("payConfirm request empty");
if (orderCode<0){
logger.warn("queryCustoms request empty");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
return crossBorderService.customsOpenApi(orderCode,tradeNo, amount);
return crossBorderService.customsOpenQueryApi(orderCode);
}
/**
* 订单支付结果确认
*
... ...
... ... @@ -3,13 +3,13 @@ package com.yohoufo.order.service.pay.alipay;
import com.alibaba.fastjson.JSONObject;
import com.yohobuy.ufo.model.order.bo.OrderInfo;
import com.yohoufo.common.utils.DateUtil;
import com.yohoufo.common.utils.RSAUtils;
import com.yohoufo.common.utils.XMLUtil;
import com.yohoufo.order.config.AlipayConfig;
import com.yohoufo.order.constants.RefundContant;
import com.yohoufo.order.model.PayQueryBo;
import com.yohoufo.order.model.PayRefundBo;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayRefundResponse;
import lombok.AccessLevel;
... ... @@ -85,11 +85,11 @@ public class AlipayCrossBorderService extends AbstractAlipayService {
}
public AlipayCustomsResponse customsOpenApi(long orderCode, String tradeNo, double amount){
public AlipayCustomsResponse customsOpenApi(long orderCode, String tradeNo, double amount, String certName, String certNo){
logger.info("enter customsOpenApi to {}, {}, {}", orderCode, tradeNo, amount);
logger.info("enter customsOpenApi to {}, {}, {}, {}, {}", orderCode, tradeNo, amount, certName, certNo);
Map<String, String> customsParam = buildOpenApiCustoms(orderCode, tradeNo, amount);
Map<String, String> customsParam = buildOpenApiCustoms(orderCode, tradeNo, amount,certName, certNo);
String respTxt = sendOpenApiRequest(String.valueOf(orderCode), customsParam, alipayConfig.crossBorderMapiUrl());
AlipayCustomsResponse customsResponse = (AlipayCustomsResponse)XMLUtil.convertXmlStrToObject(AlipayCustomsResponse.class, respTxt);
... ... @@ -101,14 +101,14 @@ public class AlipayCrossBorderService extends AbstractAlipayService {
}
public AlipayCustomsResponse customsOpenQueryApi(long orderCode){
public AlipayQueryCustomsResponse customsOpenQueryApi(long orderCode){
logger.info("enter customsOpenQueryApi to {}", orderCode);
Map<String, String> customsParam = buildOpenApiQueryCustoms(orderCode);
String respTxt = sendOpenApiRequest(String.valueOf(orderCode), customsParam, alipayConfig.crossBorderMapiUrl());
AlipayCustomsResponse customsResponse = (AlipayCustomsResponse)XMLUtil.convertXmlStrToObject(AlipayCustomsResponse.class, respTxt);
AlipayQueryCustomsResponse customsResponse = (AlipayQueryCustomsResponse)XMLUtil.convertXmlStrToObject(AlipayQueryCustomsResponse.class, respTxt);
logger.info("exit customsOpenApi, result {}", customsResponse);
... ... @@ -166,9 +166,11 @@ public class AlipayCrossBorderService extends AbstractAlipayService {
* @param orderCode
* @param tradeNo
* @param amount
* @param certName
* @param certNo
* @return
*/
private Map<String, String> buildOpenApiCustoms(long orderCode, String tradeNo, double amount){
private Map<String, String> buildOpenApiCustoms(long orderCode, String tradeNo, double amount, String certName, String certNo){
Map<String, String> params = new HashMap<>();
... ... @@ -184,6 +186,8 @@ public class AlipayCrossBorderService extends AbstractAlipayService {
params.put("amount", String.valueOf(amount));
params.put("customs_place", getCustomsPlace());
params.put("merchant_customs_name", getMerchantCustomsName());
params.put("buyer_name", certName);
params.put("buyer_id_no", certNo);
String preSignStr = getOpenApiSignString(params, true);
params.put("sign", helper().sign(preSignStr,AlipayConfig.input_charset));
... ...
package com.yohoufo.order.service.pay.alipay.bean;
import lombok.Data;
import lombok.ToString;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "alipay")
@ToString
@Data
public class AlipayQueryCustomsResponse {
private Response response;
private String is_success;
private String error;
@XmlElement(name = "error")
public String getError() {
return error;
}
@XmlElement(name="is_success")
public String getIs_success() {
return is_success;
}
@XmlElement(name = "response")
public Response getResponse() {
return response;
}
public void setResponse(Response response) {
this.response = response;
}
public void setIs_success(String is_success) {
this.is_success = is_success;
}
public static class Response {
private Alipay alipay;
@XmlElement(name = "alipay")
public Alipay getAlipay() {
return alipay;
}
public static class Records{
List<CustomsDeclare> customs_declare;
public void setAlipay(Alipay alipay) {
this.alipay = alipay;
}
public static class CustomsDeclare{
public static class Alipay {
private Records records;
private String result_code;
private String detail_error_code;
private String detail_error_des;
@XmlElement(name = "detail_error_des")
public String getDetail_error_des() {
return detail_error_des;
}
@XmlElement(name = "detail_error_code")
public String getDetail_error_code() {
return detail_error_code;
}
@XmlElement(name = "records")
public Records getRecords() {
return records;
}
public void setRecords(Records records) {
this.records = records;
}
@XmlElement(name = "result_code")
public String getResult_code() {
return result_code;
}
public void setResult_code(String result_code) {
this.result_code = result_code;
}
public void setDetail_error_code(String detail_error_code) {
this.detail_error_code = detail_error_code;
}
public void setDetail_error_des(String detail_error_des) {
this.detail_error_des = detail_error_des;
}
}
public static class Records {
private List<CustomsDeclare> records;
@XmlElement(name="customs_declare")
public List<CustomsDeclare> getRecords() {
return records;
}
public void setRecords(List<CustomsDeclare> records) {
this.records = records;
}
}
public static class CustomsDeclare {
private String out_request_no;
private String status;
@XmlElement(name = "out_request_no")
public String getOut_request_no() {
return out_request_no;
}
@XmlElement(name = "status")
public String getStatus() {
return status;
}
public void setOut_request_no(String out_request_no) {
this.out_request_no = out_request_no;
}
public void setStatus(String status) {
this.status = status;
}
}
}
}
... ...
... ... @@ -9,7 +9,8 @@ public enum CustomsErrorMsg {
CONTEXT_INCONSISTENT("不能发送多次,且参数不一致"),
SAME_CUSTOMS_DECLARE_ONCE("同一笔交易,只能在海关处申报一次"),
REQUEST_AMOUNT_EXCEED("申报的总金额超过了交易金额"),
PAYER_ENABLE_STATUS_FORBID("声明的交易中付款人的身份无法通过验证");
PAYER_ENABLE_STATUS_FORBID("支付宝账户失效"),
IDENTITY_CHECK_F("订购人与实名认证信息不一致");
private String msg;
... ...
package com.yohoufo.order.service.support;
import com.yohobuy.ufo.model.order.common.OrderAttributes;
import com.yohobuy.ufo.model.order.common.Payment;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.OrdersPayMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.OrdersPay;
import com.yohoufo.dal.user.model.ZhiMaCert;
import com.yohoufo.order.constants.ClearanceFailType;
import com.yohoufo.order.service.impl.BuyerOrderCancelService;
import com.yohoufo.order.service.pay.alipay.AlipayCrossBorderService;
import com.yohoufo.order.service.pay.alipay.bean.AlipayCustomsResponse;
import com.yohoufo.order.service.pay.alipay.bean.CustomsErrorMsg;
import com.yohoufo.order.service.proxy.UserProxyService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CustomsSupportService {
private final Logger logger = LoggerFactory.getLogger(CustomsSupportService.class);
@Autowired
OrdersPayMapper ordersPayMapper;
@Autowired
BuyerOrderMapper buyerOrderMapper;
@Autowired
private UserProxyService userProxyService;
@Autowired
private AlipayCrossBorderService crossBorderService;
@Autowired
BuyerOrderCancelService buyerOrderCancelService;
/**
* 推送支付单到海关
* @param orderCode
* @param uid
*/
public void sendPaymentInfoToCustoms(long orderCode, int uid){
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(orderCode);
if (buyerOrder == null){
logger.warn("sendPaymentInfoToCustoms orderCode info not exist {},{}", orderCode, uid);
return;
}
OrdersPay ordersPay = ordersPayMapper.selectOrdersPay(orderCode, uid);
if (ordersPay == null){
logger.warn("sendPaymentInfoToCustoms orderCode has not paid {},{}", orderCode, uid);
return;
}
// 海外+跨境支付
if (ordersPay.getPayment() == Payment.CROSS_BORDER_ALIPAY.getCode() && buyerOrder.getAttributes() == OrderAttributes.OVERSEAS_IN_STOCK.getCode()){
// 校验是否实名认证
ZhiMaCert zhimaCert = userProxyService.getRealNameInfo(uid);
if (zhimaCert == null){
logger.warn("sendPaymentInfoToCustoms: need realName cert, uid is {}", uid);
return;
}
try{
AlipayCustomsResponse alipayCustomsResponse = crossBorderService.customsOpenApi(buyerOrder.getOrderCode(),
ordersPay.getSerialNo(), ordersPay.getAmount().doubleValue(), zhimaCert.getCertName(), zhimaCert.getCertNo());
// 推送失败 || 下单人和支付人不一致
if ("F".equalsIgnoreCase(alipayCustomsResponse.getIs_success()) || "F".equalsIgnoreCase(alipayCustomsResponse.getIdentity_check())){
String error = StringUtils.isEmpty(alipayCustomsResponse.getResult_code()) ? alipayCustomsResponse.getError() : alipayCustomsResponse.getResult_code();
if ("F".equalsIgnoreCase(alipayCustomsResponse.getIdentity_check())){
error = CustomsErrorMsg.IDENTITY_CHECK_F.name();
}
// 支付单推送失败
buyerOrderCancelService.clearanceFail(buyerOrder.getOrderCode(),
CustomsErrorMsg.getCustomsError(error),
ClearanceFailType.BUYER);
logger.warn("sendPaymentInfoToCustoms error.{}, {}",orderCode, uid);
}
}catch (Exception e){
logger.warn("sendPaymentInfoToCustoms error. {}, {}, {}", orderCode, uid, e);
}
}
}
}
... ...