Authored by tanling

跨境支付

package com.yohoufo.common.utils;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
/**
* 封装了XML转换成object,object转换成XML的代码
*
* @author Steven
*
*/
public class XMLUtil {
/**
* 将对象直接转换成String类型的 XML输出
*
* @param obj
* @return
*/
public static String convertToXml(Object obj) {
// 创建输出流
StringWriter sw = new StringWriter();
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
marshaller.marshal(obj, sw);
} catch (JAXBException e) {
e.printStackTrace();
}
return sw.toString();
}
/**
* 将对象根据路径转换成xml文件
*
* @param obj
* @param path
* @return
*/
public static void convertToXml(Object obj, String path) {
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
// 创建输出流
FileWriter fw = null;
try {
fw = new FileWriter(path);
} catch (IOException e) {
e.printStackTrace();
}
marshaller.marshal(obj, fw);
} catch (JAXBException e) {
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
/**
* 将String类型的xml转换成对象
*/
public static Object convertXmlStrToObject(Class clazz, String xmlStr) {
Object xmlObject = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
// 进行将Xml转成对象的核心接口
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader sr = new StringReader(xmlStr);
xmlObject = unmarshaller.unmarshal(sr);
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlObject;
}
@SuppressWarnings("unchecked")
/**
* 将file类型的xml转换成对象
*/
public static Object convertXmlFileToObject(Class clazz, String xmlPath) {
Object xmlObject = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
FileReader fr = null;
try {
fr = new FileReader(xmlPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
xmlObject = unmarshaller.unmarshal(fr);
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlObject;
}
}
... ...
... ... @@ -5,14 +5,22 @@ 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.AlipayQueryResponse;
import com.yohoufo.order.service.pay.alipay.bean.AlipayRefundResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
... ... @@ -51,7 +59,6 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract {
return "zfbgj@yoho.cn";
}
/**
* OpenApi退款
* @param refundBo
... ... @@ -60,13 +67,30 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract {
public PayRefundBo refundOpenApi(PayRefundBo refundBo) {
logger.info("enter AliPayRefunder to refund tradeNo {}, amount {}", refundBo.getRefundOrderCode(), refundBo.getAmount());
Map<String, String> refundParams = buildOpenApiRefundParams(refundBo.getPayOrderCode(), refundBo.getRefundOrderCode(), refundBo.getAmount());
String respTxt = sendOpenApiRequest(String.valueOf(refundBo.getPayOrderCode()), refundParams, AlipayConfig.OPENAPI_URL);
String respTxt = sendOpenApiRequest(String.valueOf(refundBo.getPayOrderCode()), refundParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL);
PayRefundBo bo = refundOpenApiConvert(respTxt, refundBo);
logger.info("exit AliPayRefunder refund, refundStatus: {}, refundMsg", bo.getRefundStatus(), bo.getRefundMsg());
return bo;
}
public PayRefundBo refundOpenApiConvert(String respText, PayRefundBo bo) {
AlipayRefundResponse refundResponse = (AlipayRefundResponse)XMLUtil.convertXmlStrToObject(AlipayRefundResponse.class, respText);
if ("T".equalsIgnoreCase(refundResponse.getIs_success())){
bo.setRefundStatus(RefundContant.PAYMENT_REFUND_RESULTCODE_SUCCESS);
bo.setRefundMsg("退款申请成功");
return bo;
}
bo.setRefundStatus(RefundContant.PAYMENT_REFUND_RESULTCODE_FAIL);
bo.setRefundMsg(refundResponse.getError());
return bo;
}
/**
* openapi退款参数
* @param tradeNo
... ... @@ -86,21 +110,8 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract {
params.put("out_trade_no", tradeNo);
params.put("return_rmb_amount", String.valueOf(amount));
params.put("currency", "HKD");
params.put("app_id", getAppId());
params.put("method", "alipay.trade.refund");
params.put("charset", AlipayConfig.input_charset);
params.put("sign_type", "RSA");
params.put("timestamp", DateUtil.getCurrentTime());
params.put("version", "1.0");
JSONObject bizJson = new JSONObject();
bizJson.put("out_trade_no", tradeNo);
bizJson.put("refund_amount", amount);
bizJson.put("out_request_no", refundNo);
params.put("biz_content", bizJson.toJSONString());
params.put("gmt_return", DateUtil.formatDate(DateUtil.getCurrentTimeSecond(), DateUtil.yyyyMMddHHmmss));
params.put("product_code", "NEW_WAP_OVERSEAS_SELLER");
String preSignStr = getOpenApiSignString(params, true);
params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset));
... ... @@ -115,37 +126,22 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract {
* @return
*/
public PayQueryBo payQuery(String tradeNo, int orderCreateTime) {
// TODO 临时吃掉异常,否则无法取消
try{
Map<String, String> queryParams = buildOpenApiQueryParams(tradeNo);
String respTxt = sendOpenApiRequest(tradeNo, queryParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL);
QueryBo queryBo = JSON.parseObject(JSONObject.toJSONString(JSON.parseObject(respTxt).getJSONObject("alipay_trade_query_response")), QueryBo.class);
// 查询结果转换成 共通的对象
PayQueryBo payQueryBo = new PayQueryBo();
if ("10000".equals(queryBo.getCode())){
// 订单支付时的商户号
payQueryBo.setPayOrderCode(queryBo.getOut_trade_no());
payQueryBo.setTradeNo(queryBo.getTrade_no());
if ("TRADE_SUCCESS".equals(queryBo.getTrade_status())) {
payQueryBo.setPayStatus(true);
}else if("TRADE_CLOSED".equals(queryBo.getTrade_status())){
payQueryBo.setRefundStatus(true);
}
payQueryBo.setAmount(Double.parseDouble(queryBo.getTotal_amount()));
payQueryBo.setBuyerId(queryBo.getBuyer_user_id());
}
return payQueryBo;
}catch (Exception e){
e.printStackTrace();
}
Map<String, String> queryParams = buildOpenApiQueryParams(tradeNo);
String respTxt = sendOpenApiRequest(tradeNo, queryParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL);
AlipayQueryResponse alipayQueryResponse = (AlipayQueryResponse) XMLUtil.convertXmlStrToObject(AlipayQueryResponse.class, respTxt);
PayQueryBo payQueryBo = new PayQueryBo();
if ("T".equalsIgnoreCase(alipayQueryResponse.getIs_success())){
AlipayQueryResponse.Trade trade =alipayQueryResponse.getResponse().getTrade();
payQueryBo.setPayOrderCode(trade.getOut_trade_no());
payQueryBo.setTradeNo(trade.getTrade_no());
payQueryBo.setPayStatus(true);
payQueryBo.setAmount(Double.parseDouble(trade.getTotal_fee()));
payQueryBo.setBuyerId(trade.getBuyer_id());
}
return new PayQueryBo();
return payQueryBo;
}
... ...
package com.yohoufo.order.service.pay.alipay.bean;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "alipay")
public class AlipayQueryResponse {
/**
* 是否成功
* T:成功, F:失败
*/
private String is_success;
/**
* 错误消息
*/
private String error;
private AlipayResponse response;
public String getIs_success() {
return is_success;
}
public void setIs_success(String is_success) {
this.is_success = is_success;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public AlipayResponse getResponse() {
return response;
}
public void setResponse(AlipayResponse response) {
this.response = response;
}
public static class AlipayResponse{
private Trade trade;
public Trade getTrade() {
return trade;
}
public void setTrade(Trade trade) {
this.trade = trade;
}
}
public static class Trade{
private String buyer_email;
private String buyer_id;
private String discount;
private String out_trade_no;
private String trade_status;
private String trade_no;
private String total_fee;
public String getBuyer_email() {
return buyer_email;
}
public void setBuyer_email(String buyer_email) {
this.buyer_email = buyer_email;
}
public String getBuyer_id() {
return buyer_id;
}
public void setBuyer_id(String buyer_id) {
this.buyer_id = buyer_id;
}
public String getDiscount() {
return discount;
}
public void setDiscount(String discount) {
this.discount = discount;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getTrade_status() {
return trade_status;
}
public void setTrade_status(String trade_status) {
this.trade_status = trade_status;
}
public String getTrade_no() {
return trade_no;
}
public void setTrade_no(String trade_no) {
this.trade_no = trade_no;
}
public String getTotal_fee() {
return total_fee;
}
public void setTotal_fee(String total_fee) {
this.total_fee = total_fee;
}
}
}
... ...
package com.yohoufo.order.service.pay.alipay.bean;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "alipay")
public class AlipayRefundResponse {
/**
* 是否成功
* T:成功, F:失败
*/
private String is_success;
private String error;
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getIs_success() {
return is_success;
}
public void setIs_success(String is_success) {
this.is_success = is_success;
}
}
... ...
... ... @@ -78,6 +78,8 @@ wechat.notifyurl=http://testapi.yohops.com/payment/weixin_notify
alipay.notifyurl=http://testapi.yohops.com/payment/alipay_notify
alipay.cross.border.notifyurl=http://testapi.yohops.com/payment/alipay_notify
alipay.transfer.notifyurl=http://testapi.yohops.com/payment/alipay_transfer_notify
erp-gateway.url=http://java-yoho-erp-gateway.test3.ingress.dev.yohocorp.com/erp-gateway
... ...