Showing
5 changed files
with
317 additions
and
40 deletions
1 | +package com.yohoufo.common.utils; | ||
2 | + | ||
3 | +import java.io.FileNotFoundException; | ||
4 | +import java.io.FileReader; | ||
5 | +import java.io.FileWriter; | ||
6 | +import java.io.IOException; | ||
7 | +import java.io.StringReader; | ||
8 | +import java.io.StringWriter; | ||
9 | + | ||
10 | +import javax.xml.bind.JAXBContext; | ||
11 | +import javax.xml.bind.JAXBException; | ||
12 | +import javax.xml.bind.Marshaller; | ||
13 | +import javax.xml.bind.Unmarshaller; | ||
14 | + | ||
15 | +/** | ||
16 | + * 封装了XML转换成object,object转换成XML的代码 | ||
17 | + * | ||
18 | + * @author Steven | ||
19 | + * | ||
20 | + */ | ||
21 | +public class XMLUtil { | ||
22 | + /** | ||
23 | + * 将对象直接转换成String类型的 XML输出 | ||
24 | + * | ||
25 | + * @param obj | ||
26 | + * @return | ||
27 | + */ | ||
28 | + public static String convertToXml(Object obj) { | ||
29 | + // 创建输出流 | ||
30 | + StringWriter sw = new StringWriter(); | ||
31 | + try { | ||
32 | + // 利用jdk中自带的转换类实现 | ||
33 | + JAXBContext context = JAXBContext.newInstance(obj.getClass()); | ||
34 | + | ||
35 | + Marshaller marshaller = context.createMarshaller(); | ||
36 | + // 格式化xml输出的格式 | ||
37 | + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, | ||
38 | + Boolean.TRUE); | ||
39 | + // 将对象转换成输出流形式的xml | ||
40 | + marshaller.marshal(obj, sw); | ||
41 | + } catch (JAXBException e) { | ||
42 | + e.printStackTrace(); | ||
43 | + } | ||
44 | + return sw.toString(); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * 将对象根据路径转换成xml文件 | ||
49 | + * | ||
50 | + * @param obj | ||
51 | + * @param path | ||
52 | + * @return | ||
53 | + */ | ||
54 | + public static void convertToXml(Object obj, String path) { | ||
55 | + try { | ||
56 | + // 利用jdk中自带的转换类实现 | ||
57 | + JAXBContext context = JAXBContext.newInstance(obj.getClass()); | ||
58 | + | ||
59 | + Marshaller marshaller = context.createMarshaller(); | ||
60 | + // 格式化xml输出的格式 | ||
61 | + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, | ||
62 | + Boolean.TRUE); | ||
63 | + // 将对象转换成输出流形式的xml | ||
64 | + // 创建输出流 | ||
65 | + FileWriter fw = null; | ||
66 | + try { | ||
67 | + fw = new FileWriter(path); | ||
68 | + } catch (IOException e) { | ||
69 | + e.printStackTrace(); | ||
70 | + } | ||
71 | + marshaller.marshal(obj, fw); | ||
72 | + } catch (JAXBException e) { | ||
73 | + e.printStackTrace(); | ||
74 | + } | ||
75 | + } | ||
76 | + | ||
77 | + @SuppressWarnings("unchecked") | ||
78 | + /** | ||
79 | + * 将String类型的xml转换成对象 | ||
80 | + */ | ||
81 | + public static Object convertXmlStrToObject(Class clazz, String xmlStr) { | ||
82 | + Object xmlObject = null; | ||
83 | + try { | ||
84 | + JAXBContext context = JAXBContext.newInstance(clazz); | ||
85 | + // 进行将Xml转成对象的核心接口 | ||
86 | + Unmarshaller unmarshaller = context.createUnmarshaller(); | ||
87 | + StringReader sr = new StringReader(xmlStr); | ||
88 | + xmlObject = unmarshaller.unmarshal(sr); | ||
89 | + } catch (JAXBException e) { | ||
90 | + e.printStackTrace(); | ||
91 | + } | ||
92 | + return xmlObject; | ||
93 | + } | ||
94 | + | ||
95 | + @SuppressWarnings("unchecked") | ||
96 | + /** | ||
97 | + * 将file类型的xml转换成对象 | ||
98 | + */ | ||
99 | + public static Object convertXmlFileToObject(Class clazz, String xmlPath) { | ||
100 | + Object xmlObject = null; | ||
101 | + try { | ||
102 | + JAXBContext context = JAXBContext.newInstance(clazz); | ||
103 | + Unmarshaller unmarshaller = context.createUnmarshaller(); | ||
104 | + FileReader fr = null; | ||
105 | + try { | ||
106 | + fr = new FileReader(xmlPath); | ||
107 | + } catch (FileNotFoundException e) { | ||
108 | + e.printStackTrace(); | ||
109 | + } | ||
110 | + xmlObject = unmarshaller.unmarshal(fr); | ||
111 | + } catch (JAXBException e) { | ||
112 | + e.printStackTrace(); | ||
113 | + } | ||
114 | + return xmlObject; | ||
115 | + } | ||
116 | +} | ||
117 | + |
@@ -5,14 +5,22 @@ import com.alibaba.fastjson.JSONObject; | @@ -5,14 +5,22 @@ import com.alibaba.fastjson.JSONObject; | ||
5 | import com.yohobuy.ufo.model.order.bo.OrderInfo; | 5 | import com.yohobuy.ufo.model.order.bo.OrderInfo; |
6 | import com.yohoufo.common.utils.DateUtil; | 6 | import com.yohoufo.common.utils.DateUtil; |
7 | import com.yohoufo.common.utils.RSAUtils; | 7 | import com.yohoufo.common.utils.RSAUtils; |
8 | +import com.yohoufo.common.utils.XMLUtil; | ||
8 | import com.yohoufo.order.config.AlipayConfig; | 9 | import com.yohoufo.order.config.AlipayConfig; |
10 | +import com.yohoufo.order.constants.RefundContant; | ||
9 | import com.yohoufo.order.model.PayQueryBo; | 11 | import com.yohoufo.order.model.PayQueryBo; |
10 | import com.yohoufo.order.model.PayRefundBo; | 12 | import com.yohoufo.order.model.PayRefundBo; |
13 | +import com.yohoufo.order.service.pay.alipay.bean.AlipayQueryResponse; | ||
14 | +import com.yohoufo.order.service.pay.alipay.bean.AlipayRefundResponse; | ||
15 | +import org.apache.commons.lang3.StringUtils; | ||
16 | +import org.apache.http.client.utils.DateUtils; | ||
11 | import org.slf4j.Logger; | 17 | import org.slf4j.Logger; |
12 | import org.slf4j.LoggerFactory; | 18 | import org.slf4j.LoggerFactory; |
19 | +import org.springframework.beans.factory.annotation.Value; | ||
13 | import org.springframework.stereotype.Service; | 20 | import org.springframework.stereotype.Service; |
14 | import java.math.BigDecimal; | 21 | import java.math.BigDecimal; |
15 | import java.net.URLEncoder; | 22 | import java.net.URLEncoder; |
23 | +import java.util.Date; | ||
16 | import java.util.HashMap; | 24 | import java.util.HashMap; |
17 | import java.util.Map; | 25 | import java.util.Map; |
18 | 26 | ||
@@ -51,7 +59,6 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | @@ -51,7 +59,6 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | ||
51 | return "zfbgj@yoho.cn"; | 59 | return "zfbgj@yoho.cn"; |
52 | } | 60 | } |
53 | 61 | ||
54 | - | ||
55 | /** | 62 | /** |
56 | * OpenApi退款 | 63 | * OpenApi退款 |
57 | * @param refundBo | 64 | * @param refundBo |
@@ -60,13 +67,30 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | @@ -60,13 +67,30 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | ||
60 | public PayRefundBo refundOpenApi(PayRefundBo refundBo) { | 67 | public PayRefundBo refundOpenApi(PayRefundBo refundBo) { |
61 | logger.info("enter AliPayRefunder to refund tradeNo {}, amount {}", refundBo.getRefundOrderCode(), refundBo.getAmount()); | 68 | logger.info("enter AliPayRefunder to refund tradeNo {}, amount {}", refundBo.getRefundOrderCode(), refundBo.getAmount()); |
62 | Map<String, String> refundParams = buildOpenApiRefundParams(refundBo.getPayOrderCode(), refundBo.getRefundOrderCode(), refundBo.getAmount()); | 69 | Map<String, String> refundParams = buildOpenApiRefundParams(refundBo.getPayOrderCode(), refundBo.getRefundOrderCode(), refundBo.getAmount()); |
63 | - String respTxt = sendOpenApiRequest(String.valueOf(refundBo.getPayOrderCode()), refundParams, AlipayConfig.OPENAPI_URL); | 70 | + String respTxt = sendOpenApiRequest(String.valueOf(refundBo.getPayOrderCode()), refundParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL); |
71 | + | ||
64 | PayRefundBo bo = refundOpenApiConvert(respTxt, refundBo); | 72 | PayRefundBo bo = refundOpenApiConvert(respTxt, refundBo); |
65 | logger.info("exit AliPayRefunder refund, refundStatus: {}, refundMsg", bo.getRefundStatus(), bo.getRefundMsg()); | 73 | logger.info("exit AliPayRefunder refund, refundStatus: {}, refundMsg", bo.getRefundStatus(), bo.getRefundMsg()); |
66 | return bo; | 74 | return bo; |
67 | } | 75 | } |
68 | 76 | ||
69 | 77 | ||
78 | + public PayRefundBo refundOpenApiConvert(String respText, PayRefundBo bo) { | ||
79 | + AlipayRefundResponse refundResponse = (AlipayRefundResponse)XMLUtil.convertXmlStrToObject(AlipayRefundResponse.class, respText); | ||
80 | + | ||
81 | + if ("T".equalsIgnoreCase(refundResponse.getIs_success())){ | ||
82 | + bo.setRefundStatus(RefundContant.PAYMENT_REFUND_RESULTCODE_SUCCESS); | ||
83 | + bo.setRefundMsg("退款申请成功"); | ||
84 | + return bo; | ||
85 | + } | ||
86 | + | ||
87 | + bo.setRefundStatus(RefundContant.PAYMENT_REFUND_RESULTCODE_FAIL); | ||
88 | + bo.setRefundMsg(refundResponse.getError()); | ||
89 | + | ||
90 | + return bo; | ||
91 | + } | ||
92 | + | ||
93 | + | ||
70 | /** | 94 | /** |
71 | * openapi退款参数 | 95 | * openapi退款参数 |
72 | * @param tradeNo | 96 | * @param tradeNo |
@@ -86,21 +110,8 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | @@ -86,21 +110,8 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | ||
86 | params.put("out_trade_no", tradeNo); | 110 | params.put("out_trade_no", tradeNo); |
87 | params.put("return_rmb_amount", String.valueOf(amount)); | 111 | params.put("return_rmb_amount", String.valueOf(amount)); |
88 | params.put("currency", "HKD"); | 112 | params.put("currency", "HKD"); |
89 | - | ||
90 | - | ||
91 | - | ||
92 | - params.put("app_id", getAppId()); | ||
93 | - params.put("method", "alipay.trade.refund"); | ||
94 | - params.put("charset", AlipayConfig.input_charset); | ||
95 | - params.put("sign_type", "RSA"); | ||
96 | - params.put("timestamp", DateUtil.getCurrentTime()); | ||
97 | - params.put("version", "1.0"); | ||
98 | - | ||
99 | - JSONObject bizJson = new JSONObject(); | ||
100 | - bizJson.put("out_trade_no", tradeNo); | ||
101 | - bizJson.put("refund_amount", amount); | ||
102 | - bizJson.put("out_request_no", refundNo); | ||
103 | - params.put("biz_content", bizJson.toJSONString()); | 113 | + params.put("gmt_return", DateUtil.formatDate(DateUtil.getCurrentTimeSecond(), DateUtil.yyyyMMddHHmmss)); |
114 | + params.put("product_code", "NEW_WAP_OVERSEAS_SELLER"); | ||
104 | 115 | ||
105 | String preSignStr = getOpenApiSignString(params, true); | 116 | String preSignStr = getOpenApiSignString(params, true); |
106 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); | 117 | params.put("sign", RSAUtils.sign(preSignStr, getRsaPrivateKey(), AlipayConfig.input_charset)); |
@@ -115,37 +126,22 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | @@ -115,37 +126,22 @@ public class AlipayCrossBorderService extends AlipayServiceAbstract { | ||
115 | * @return | 126 | * @return |
116 | */ | 127 | */ |
117 | public PayQueryBo payQuery(String tradeNo, int orderCreateTime) { | 128 | public PayQueryBo payQuery(String tradeNo, int orderCreateTime) { |
118 | - // TODO 临时吃掉异常,否则无法取消 | ||
119 | - try{ | ||
120 | Map<String, String> queryParams = buildOpenApiQueryParams(tradeNo); | 129 | Map<String, String> queryParams = buildOpenApiQueryParams(tradeNo); |
121 | String respTxt = sendOpenApiRequest(tradeNo, queryParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL); | 130 | String respTxt = sendOpenApiRequest(tradeNo, queryParams, AlipayConfig.CROSS_BORDER_OPENAPI_URL); |
122 | - QueryBo queryBo = JSON.parseObject(JSONObject.toJSONString(JSON.parseObject(respTxt).getJSONObject("alipay_trade_query_response")), QueryBo.class); | ||
123 | - | ||
124 | - // 查询结果转换成 共通的对象 | ||
125 | - PayQueryBo payQueryBo = new PayQueryBo(); | ||
126 | 131 | ||
127 | - if ("10000".equals(queryBo.getCode())){ | ||
128 | - // 订单支付时的商户号 | ||
129 | - payQueryBo.setPayOrderCode(queryBo.getOut_trade_no()); | ||
130 | - payQueryBo.setTradeNo(queryBo.getTrade_no()); | 132 | + AlipayQueryResponse alipayQueryResponse = (AlipayQueryResponse) XMLUtil.convertXmlStrToObject(AlipayQueryResponse.class, respTxt); |
131 | 133 | ||
132 | - if ("TRADE_SUCCESS".equals(queryBo.getTrade_status())) { | 134 | + PayQueryBo payQueryBo = new PayQueryBo(); |
135 | + if ("T".equalsIgnoreCase(alipayQueryResponse.getIs_success())){ | ||
136 | + AlipayQueryResponse.Trade trade =alipayQueryResponse.getResponse().getTrade(); | ||
137 | + payQueryBo.setPayOrderCode(trade.getOut_trade_no()); | ||
138 | + payQueryBo.setTradeNo(trade.getTrade_no()); | ||
133 | payQueryBo.setPayStatus(true); | 139 | payQueryBo.setPayStatus(true); |
134 | - | ||
135 | - }else if("TRADE_CLOSED".equals(queryBo.getTrade_status())){ | ||
136 | - payQueryBo.setRefundStatus(true); | ||
137 | - } | ||
138 | - | ||
139 | - payQueryBo.setAmount(Double.parseDouble(queryBo.getTotal_amount())); | ||
140 | - payQueryBo.setBuyerId(queryBo.getBuyer_user_id()); | 140 | + payQueryBo.setAmount(Double.parseDouble(trade.getTotal_fee())); |
141 | + payQueryBo.setBuyerId(trade.getBuyer_id()); | ||
141 | } | 142 | } |
142 | 143 | ||
143 | return payQueryBo; | 144 | return payQueryBo; |
144 | - }catch (Exception e){ | ||
145 | - e.printStackTrace(); | ||
146 | - } | ||
147 | - | ||
148 | - return new PayQueryBo(); | ||
149 | } | 145 | } |
150 | 146 | ||
151 | 147 |
1 | +package com.yohoufo.order.service.pay.alipay.bean; | ||
2 | + | ||
3 | +import javax.xml.bind.annotation.XmlAccessType; | ||
4 | +import javax.xml.bind.annotation.XmlAccessorType; | ||
5 | +import javax.xml.bind.annotation.XmlRootElement; | ||
6 | + | ||
7 | +@XmlAccessorType(XmlAccessType.FIELD) | ||
8 | +@XmlRootElement(name = "alipay") | ||
9 | +public class AlipayQueryResponse { | ||
10 | + | ||
11 | + /** | ||
12 | + * 是否成功 | ||
13 | + * T:成功, F:失败 | ||
14 | + */ | ||
15 | + private String is_success; | ||
16 | + | ||
17 | + /** | ||
18 | + * 错误消息 | ||
19 | + */ | ||
20 | + private String error; | ||
21 | + | ||
22 | + private AlipayResponse response; | ||
23 | + | ||
24 | + public String getIs_success() { | ||
25 | + return is_success; | ||
26 | + } | ||
27 | + | ||
28 | + public void setIs_success(String is_success) { | ||
29 | + this.is_success = is_success; | ||
30 | + } | ||
31 | + | ||
32 | + public String getError() { | ||
33 | + return error; | ||
34 | + } | ||
35 | + | ||
36 | + public void setError(String error) { | ||
37 | + this.error = error; | ||
38 | + } | ||
39 | + | ||
40 | + public AlipayResponse getResponse() { | ||
41 | + return response; | ||
42 | + } | ||
43 | + | ||
44 | + public void setResponse(AlipayResponse response) { | ||
45 | + this.response = response; | ||
46 | + } | ||
47 | + | ||
48 | + public static class AlipayResponse{ | ||
49 | + private Trade trade; | ||
50 | + | ||
51 | + public Trade getTrade() { | ||
52 | + return trade; | ||
53 | + } | ||
54 | + | ||
55 | + public void setTrade(Trade trade) { | ||
56 | + this.trade = trade; | ||
57 | + } | ||
58 | + } | ||
59 | + | ||
60 | + public static class Trade{ | ||
61 | + private String buyer_email; | ||
62 | + private String buyer_id; | ||
63 | + private String discount; | ||
64 | + private String out_trade_no; | ||
65 | + private String trade_status; | ||
66 | + private String trade_no; | ||
67 | + private String total_fee; | ||
68 | + | ||
69 | + public String getBuyer_email() { | ||
70 | + return buyer_email; | ||
71 | + } | ||
72 | + | ||
73 | + public void setBuyer_email(String buyer_email) { | ||
74 | + this.buyer_email = buyer_email; | ||
75 | + } | ||
76 | + | ||
77 | + public String getBuyer_id() { | ||
78 | + return buyer_id; | ||
79 | + } | ||
80 | + | ||
81 | + public void setBuyer_id(String buyer_id) { | ||
82 | + this.buyer_id = buyer_id; | ||
83 | + } | ||
84 | + | ||
85 | + public String getDiscount() { | ||
86 | + return discount; | ||
87 | + } | ||
88 | + | ||
89 | + public void setDiscount(String discount) { | ||
90 | + this.discount = discount; | ||
91 | + } | ||
92 | + | ||
93 | + public String getOut_trade_no() { | ||
94 | + return out_trade_no; | ||
95 | + } | ||
96 | + | ||
97 | + public void setOut_trade_no(String out_trade_no) { | ||
98 | + this.out_trade_no = out_trade_no; | ||
99 | + } | ||
100 | + | ||
101 | + public String getTrade_status() { | ||
102 | + return trade_status; | ||
103 | + } | ||
104 | + | ||
105 | + public void setTrade_status(String trade_status) { | ||
106 | + this.trade_status = trade_status; | ||
107 | + } | ||
108 | + | ||
109 | + public String getTrade_no() { | ||
110 | + return trade_no; | ||
111 | + } | ||
112 | + | ||
113 | + public void setTrade_no(String trade_no) { | ||
114 | + this.trade_no = trade_no; | ||
115 | + } | ||
116 | + | ||
117 | + public String getTotal_fee() { | ||
118 | + return total_fee; | ||
119 | + } | ||
120 | + | ||
121 | + public void setTotal_fee(String total_fee) { | ||
122 | + this.total_fee = total_fee; | ||
123 | + } | ||
124 | + } | ||
125 | + | ||
126 | + | ||
127 | +} |
1 | +package com.yohoufo.order.service.pay.alipay.bean; | ||
2 | + | ||
3 | +import javax.xml.bind.annotation.XmlAccessType; | ||
4 | +import javax.xml.bind.annotation.XmlAccessorType; | ||
5 | +import javax.xml.bind.annotation.XmlRootElement; | ||
6 | + | ||
7 | +@XmlAccessorType(XmlAccessType.FIELD) | ||
8 | +@XmlRootElement(name = "alipay") | ||
9 | +public class AlipayRefundResponse { | ||
10 | + | ||
11 | + /** | ||
12 | + * 是否成功 | ||
13 | + * T:成功, F:失败 | ||
14 | + */ | ||
15 | + private String is_success; | ||
16 | + | ||
17 | + | ||
18 | + private String error; | ||
19 | + | ||
20 | + public String getError() { | ||
21 | + return error; | ||
22 | + } | ||
23 | + | ||
24 | + public void setError(String error) { | ||
25 | + this.error = error; | ||
26 | + } | ||
27 | + | ||
28 | + public String getIs_success() { | ||
29 | + return is_success; | ||
30 | + } | ||
31 | + | ||
32 | + public void setIs_success(String is_success) { | ||
33 | + this.is_success = is_success; | ||
34 | + } | ||
35 | +} |
@@ -78,6 +78,8 @@ wechat.notifyurl=http://testapi.yohops.com/payment/weixin_notify | @@ -78,6 +78,8 @@ wechat.notifyurl=http://testapi.yohops.com/payment/weixin_notify | ||
78 | 78 | ||
79 | alipay.notifyurl=http://testapi.yohops.com/payment/alipay_notify | 79 | alipay.notifyurl=http://testapi.yohops.com/payment/alipay_notify |
80 | 80 | ||
81 | +alipay.cross.border.notifyurl=http://testapi.yohops.com/payment/alipay_notify | ||
82 | + | ||
81 | alipay.transfer.notifyurl=http://testapi.yohops.com/payment/alipay_transfer_notify | 83 | alipay.transfer.notifyurl=http://testapi.yohops.com/payment/alipay_transfer_notify |
82 | 84 | ||
83 | erp-gateway.url=http://java-yoho-erp-gateway.test3.ingress.dev.yohocorp.com/erp-gateway | 85 | erp-gateway.url=http://java-yoho-erp-gateway.test3.ingress.dev.yohocorp.com/erp-gateway |
-
Please register or login to post a comment