From 47c7b67eb780109161b0f65e8960e685ff54c46b Mon Sep 17 00:00:00 2001 From: wangning <164851225@qq.com> Date: Fri, 29 Dec 2017 09:42:33 +0800 Subject: [PATCH] add ofei --- .../manage/mappers/ofei/TopUpOrderMapper.java | 24 ++ .../payment/manage/ofei/core/OfeiClient.java | 20 ++ .../payment/manage/ofei/core/OfeiServer.java | 13 + .../manage/ofei/core/impl/OfeiClientImpl.java | 265 ++++++++++++++++++ .../manage/ofei/core/impl/OfeiServceImpl.java | 77 +++++ .../manage/ofei/web/OfeiNotifyController.java | 33 +++ 6 files changed, 432 insertions(+) create mode 100644 src/main/java/au/com/royalpay/payment/manage/mappers/ofei/TopUpOrderMapper.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiClient.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiServer.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiServceImpl.java create mode 100644 src/main/java/au/com/royalpay/payment/manage/ofei/web/OfeiNotifyController.java diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/ofei/TopUpOrderMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/ofei/TopUpOrderMapper.java new file mode 100644 index 000000000..253b4799f --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/ofei/TopUpOrderMapper.java @@ -0,0 +1,24 @@ +package au.com.royalpay.payment.manage.mappers.ofei; + +import com.alibaba.fastjson.JSONObject; + +import org.apache.ibatis.annotations.Param; + +import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper; +import cn.yixblog.support.mybatis.autosql.annotations.AutoSql; +import cn.yixblog.support.mybatis.autosql.annotations.SqlType; + +/** + * Created by yixian on 2016-06-25. + */ +@AutoMapper(tablename = "top_up_order", pkName = "id") +public interface TopUpOrderMapper { + @AutoSql(type = SqlType.INSERT) + void save(JSONObject order); + + @AutoSql(type = SqlType.UPDATE) + void update(JSONObject order); + + @AutoSql(type = SqlType.SELECT) + JSONObject findById(@Param("id") String id); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiClient.java b/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiClient.java new file mode 100644 index 000000000..f16a47b7b --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiClient.java @@ -0,0 +1,20 @@ +package au.com.royalpay.payment.manage.ofei.core; + + +import org.dom4j.Element; + +/** + * Created by wangning on 2017/12/7. + */ +public interface OfeiClient { + + void phoneTopUp(String price, boolean quickTopUp, String topUpDelayTime, String phoneNumber); + + void chekcPhoneNumber(String phoneNumber, String price); + + void flowTopUp(String phoneNumber, String flowValue, String perValue); + + void checkFlow(String phoneNumber, String flowValue, String perValue); + + Element checkOrderStatus(String orderId); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiServer.java b/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiServer.java new file mode 100644 index 000000000..842cc7400 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/core/OfeiServer.java @@ -0,0 +1,13 @@ +package au.com.royalpay.payment.manage.ofei.core; + +import com.alibaba.fastjson.JSONObject; + +/** + * Created by wangning on 2017/12/8. + */ +public interface OfeiServer { + void checkOrderForNotify(JSONObject param); + + void checkOrder(String orderId); + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java new file mode 100644 index 000000000..b8b6264b7 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiClientImpl.java @@ -0,0 +1,265 @@ +package au.com.royalpay.payment.manage.ofei.core.impl; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.annotation.Resource; + +import org.apache.commons.lang.RandomStringUtils; +import org.apache.commons.lang.time.DateFormatUtils; +import org.apache.http.NameValuePair; +import org.apache.http.message.BasicNameValuePair; +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestMethod; + +import com.alibaba.fastjson.JSONObject; + +import au.com.royalpay.payment.core.exceptions.ChannelNetworkException; +import au.com.royalpay.payment.manage.mappers.ofei.TopUpOrderMapper; +import au.com.royalpay.payment.manage.ofei.core.OfeiClient; +import au.com.royalpay.payment.tools.codec.MD5Hash; +import au.com.royalpay.payment.tools.exceptions.BadRequestException; +import au.com.royalpay.payment.tools.exceptions.ServerErrorException; + +import cn.yixblog.platform.http.HttpRequestGenerator; +import cn.yixblog.platform.http.HttpRequestResult; + +/** + * Created by wangning on 2017/12/7. + */ +@Service +public class OfeiClientImpl implements OfeiClient { + private Logger logger = LoggerFactory.getLogger(getClass()); + + @Value("${app.ofei.md5-key}") + private String md5key; + @Value("${app.ofei.pwd}") + private String pwd; + @Value("${app.ofei.sp-code}") + private String spCode; + @Resource + private TopUpOrderMapper topUpOrderMapper; + + private final String checkUrl = "http://api2.ofpay.com/telcheck.do"; + private final String topUPUrl = "http://api2.ofpay.com/onlineorder.do"; + private final String flowTopUPUrl = "http://api2.ofpay.com/flowOrder.do"; + private final String checkFlowUrl = "http://api2.ofpay.com/flowCheck.do"; + private final String checkOrderUrl = "http://api2.ofpay.com/queryOrderInfo.do"; + + @Override + public void phoneTopUp(String price, boolean quickTopUp, String topUpDelayTime, String phoneNumber) { + chekcPhoneNumber(phoneNumber, price); + String orderId = "ofei-" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + "-" + RandomStringUtils.random(5, true, true); + List params = new ArrayList<>(); + String md5Pwd = MD5Hash.hashToHex(pwd); + Date now = new Date(); + params.add(new BasicNameValuePair("userid", spCode)); + params.add(new BasicNameValuePair("userpws", md5Pwd)); + params.add(new BasicNameValuePair("cardid", quickTopUp ? "140101" : "170101")); + params.add(new BasicNameValuePair("cardnum", String.valueOf(price))); + if (!quickTopUp) { + params.add(new BasicNameValuePair("mctype", topUpDelayTime)); + } + params.add(new BasicNameValuePair("sporder_id", orderId)); + params.add(new BasicNameValuePair("sporder_time", DateFormatUtils.format(now, "yyyyMMddHHmmss"))); + params.add(new BasicNameValuePair("game_userid", phoneNumber)); + + saveOrder(orderId, now, "1", price, phoneNumber); + HttpRequestGenerator req = initRequest(topUPUrl, signAndEncryptForm(params), RequestMethod.GET); + Element respXml = executeRequestXML(req, "ofei phone top up fail"); + handleResponse(orderId, respXml); + } + + private void handleResponse(String orderId, Element respXml) { + JSONObject detail = new JSONObject(); + if ("1".equals(respXml.elementText("retcode"))) { + detail.put("cardname", respXml.elementText("cardname")); + String gameState = respXml.elementText("game_state"); + switch (gameState) { + case "1": + updateOrder(orderId, "1", detail); + break; + case "0": + updateOrder(orderId, "10", detail); + break; + case "9": + updateOrder(orderId, "20", detail); + break; + } + }else { + detail.put("err_msg",respXml.elementText("err_msg")); + updateOrder(orderId,"99",detail); + } + } + + @Override + public void chekcPhoneNumber(String phoneNumber, String price) { + List params = new ArrayList<>(); + params.add(new BasicNameValuePair("userid", spCode)); + params.add(new BasicNameValuePair("phoneno", phoneNumber)); + params.add(new BasicNameValuePair("price", String.valueOf(price))); + HttpRequestGenerator req = initRequest(checkUrl, params, RequestMethod.GET); + String respStr = executeRequestString(req, "ofei phoneNumberCheck"); + String resultCode = respStr.substring(0, respStr.indexOf("#")); + switch (resultCode) { + case "1": + break; + case "321": + throw new BadRequestException("暂时不支持此类手机号的充值"); + case "11": + throw new BadRequestException("运营商地区维护,暂不能充值"); + default: + throw new ServerErrorException("系统异常"); + } + } + + @Override + public void flowTopUp(String phoneNumber, String flowValue, String perValue) { + checkFlow(phoneNumber, flowValue, perValue); + String orderId = "ofei-" + DateFormatUtils.format(new Date(), "yyyyMMddHHmmss") + "-" + RandomStringUtils.random(5, true, true); + List params = new ArrayList<>(); + String md5Pwd = MD5Hash.hashToHex(pwd); + params.add(new BasicNameValuePair("userid", spCode)); + params.add(new BasicNameValuePair("userpws", md5Pwd)); + params.add(new BasicNameValuePair("phoneno", phoneNumber)); + params.add(new BasicNameValuePair("perValue", perValue)); + params.add(new BasicNameValuePair("flowValue", flowValue)); + params.add(new BasicNameValuePair("range", "2")); + params.add(new BasicNameValuePair("effectStartTime", "1")); + params.add(new BasicNameValuePair("effectTime", "1")); + params.add(new BasicNameValuePair("netType", "4G")); + params.add(new BasicNameValuePair("sporderId", orderId)); + saveOrder(orderId, new Date(), "2", perValue, phoneNumber); + HttpRequestGenerator req = initRequest(flowTopUPUrl, signAndEncryptForm(params), RequestMethod.GET); + Element respXml = executeRequestXML(req, "ofei flowTopUp"); + handleResponse(orderId, respXml); + } + + @Override + public void checkFlow(String phoneNumber, String flowValue, String perValue) { + List params = new ArrayList<>(); + String md5Pwd = MD5Hash.hashToHex(pwd); + params.add(new BasicNameValuePair("userid", spCode)); + params.add(new BasicNameValuePair("userpws", md5Pwd)); + params.add(new BasicNameValuePair("phoneno", phoneNumber)); + params.add(new BasicNameValuePair("perValue", perValue)); + params.add(new BasicNameValuePair("flowValue", flowValue)); + params.add(new BasicNameValuePair("range", "2")); + params.add(new BasicNameValuePair("effectStartTime", "1")); + params.add(new BasicNameValuePair("effectTime", "1")); + params.add(new BasicNameValuePair("netType", "4G")); + HttpRequestGenerator req = initRequest(checkFlowUrl, signAndEncryptForm(params), RequestMethod.GET); + Element respXml = executeRequestXML(req, "ofei flowCheck"); + String returnCode = respXml.elementText("retcode"); + switch (returnCode) { + case "1": + break; + case "11": + throw new BadRequestException(respXml.elementText("err_msg")); + default: + throw new ServerErrorException("系统异常"); + } + } + + @Override + public Element checkOrderStatus(String orderId) { + List params = new ArrayList<>(); + String md5Pwd = MD5Hash.hashToHex(pwd); + params.add(new BasicNameValuePair("userid", spCode)); + params.add(new BasicNameValuePair("userpws", md5Pwd)); + params.add(new BasicNameValuePair("sporder_id", orderId)); + HttpRequestGenerator req = initRequest(checkOrderUrl,signAndEncryptForm(params), RequestMethod.GET); + return executeRequestXML(req,"ofei check order status error"); + } + + private List signAndEncryptForm(List params) { + String signStr = ""; + for (NameValuePair pair : params) { + if ("md5Str,retUrl,version,mctype,md5_str,ret_url,buyNum".contains(pair.getName())) { + continue; + } else { + signStr += pair.getValue(); + } + } + signStr += md5key; + params.add(new BasicNameValuePair("md5_str", MD5Hash.hashToHex(signStr).toUpperCase())); + params.add(new BasicNameValuePair("version", "6.0")); + params.add(new BasicNameValuePair("md5Str", MD5Hash.hashToHex(signStr).toUpperCase())); + return params; + } + + private HttpRequestGenerator initRequest(String url, List params, RequestMethod requestMethod) { + HttpRequestGenerator gen = new HttpRequestGenerator(url, requestMethod); + for (NameValuePair pair : params) { + gen.addQueryString(pair.getName(), pair.getValue()); + } + return gen; + } + + private Element executeRequestXML(HttpRequestGenerator gen, String errMsg) { + try { + HttpRequestResult res = gen.execute(); + if (res.isSuccess()) { + byte[] respArr = res.getResponseContentBytes(); + String respStr = new String(respArr, "GB2312"); + logger.debug("ofei server response:" + respStr); + Document respXml = DocumentHelper.parseText(respStr); + Element respRoot = respXml.getRootElement(); + return respRoot; + } else { + throw new ChannelNetworkException(errMsg + "-->Network Error:" + res.getStatusCode()); + } + } catch (URISyntaxException | DocumentException | IOException e) { + throw new ChannelNetworkException(errMsg + "-->Network Error", e); + } + } + + private String executeRequestString(HttpRequestGenerator gen, String errMsg) { + try { + HttpRequestResult res = gen.execute(); + if (res.isSuccess()) { + byte[] respArr = res.getResponseContentBytes(); + String respStr = new String(respArr, "GB2312"); + logger.debug("ofei server response:" + respStr); + return respStr; + } else { + throw new ChannelNetworkException(errMsg + "-->Network Error:" + res.getStatusCode()); + } + } catch (URISyntaxException | IOException e) { + throw new ChannelNetworkException(errMsg + "-->Network Error", e); + } + + } + + private void saveOrder(String orderId, Date now, String type, String price, String customerNumber) { + JSONObject order = new JSONObject(); + order.put("id", orderId); + order.put("create_time", now); + order.put("type", type); + order.put("amount", price); + order.put("customer_number", customerNumber); + order.put("status", "0"); + topUpOrderMapper.save(order); + } + + private void updateOrder(String orderId, String status, JSONObject detail) { + JSONObject record = new JSONObject(); + record.put("id", orderId); + record.put("status", status); + record.put("detail", detail.toJSONString()); + topUpOrderMapper.update(record); + } + + + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiServceImpl.java b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiServceImpl.java new file mode 100644 index 000000000..f4ab6b2bb --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/core/impl/OfeiServceImpl.java @@ -0,0 +1,77 @@ +package au.com.royalpay.payment.manage.ofei.core.impl; + +import javax.annotation.Resource; + +import org.dom4j.Element; +import org.springframework.stereotype.Service; + +import com.alibaba.fastjson.JSONObject; + +import au.com.royalpay.payment.manage.mappers.ofei.TopUpOrderMapper; +import au.com.royalpay.payment.manage.ofei.core.OfeiClient; +import au.com.royalpay.payment.manage.ofei.core.OfeiServer; + +/** + * Created by wangning on 2017/12/8. + */ +@Service +public class OfeiServceImpl implements OfeiServer { + @Resource + private TopUpOrderMapper topUpOrderMapper; + @Resource + private OfeiClient ofeiClient; + + @Override + public void checkOrderForNotify(JSONObject param) { + JSONObject order = topUpOrderMapper.findById(param.getString("orderId")); + if (order == null) { + return; + } + String ret_code = param.getString("ret_code"); + switch (ret_code) { + case "1": + order.put("status", "1"); + break; + case "9": + order.put("status", 20); + JSONObject detail = new JSONObject(); + detail.put("err_msg", param.getString("err_msg")); + order.put("detail", detail.toJSONString()); + } + topUpOrderMapper.update(order); + + } + + @Override + public void checkOrder(String orderId) { + JSONObject order = topUpOrderMapper.findById(orderId); + if (order==null){ + return; + } + Element orderStats = ofeiClient.checkOrderStatus(orderId); + JSONObject detail = new JSONObject(); + if ("1".equals(orderStats.elementText("retcode"))) { + detail.put("cardname", orderStats.elementText("cardname")); + order.put("detail",detail.toJSONString()); + String gameState = orderStats.elementText("game_state"); + switch (gameState) { + case "1": + order.put("status","1"); + break; + case "0": + order.put("status","10"); + break; + case "9": + order.put("status","20"); + break; + } + + }else { + order.put("status","99"); + order.put("detail",order.getJSONObject("detail").put("err_msg",orderStats.elementText("err_msg"))); + detail.put("err_msg",orderStats.elementText("err_msg")); + } + topUpOrderMapper.update(order); + } + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/ofei/web/OfeiNotifyController.java b/src/main/java/au/com/royalpay/payment/manage/ofei/web/OfeiNotifyController.java new file mode 100644 index 000000000..7acb3e52f --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/ofei/web/OfeiNotifyController.java @@ -0,0 +1,33 @@ +package au.com.royalpay.payment.manage.ofei.web; + +import au.com.royalpay.payment.manage.ofei.core.OfeiServer; + +import com.alibaba.fastjson.JSONObject; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; + +/** + * Created by wangning on 2017/12/8. + */ +@RestController +@RequestMapping("/ofei/notice") +public class OfeiNotifyController { + @Resource + private OfeiServer ofeiServer; + + @RequestMapping(value = "/{order_id}",method = {RequestMethod.GET, RequestMethod.POST}) + public void listNotices(@PathVariable String order_id, @RequestParam String ret_code, @RequestParam String ordersuccesstime, @RequestParam String err_msg) { + JSONObject params =new JSONObject(); + params.put("orderId",order_id); + params.put("ret_code",ret_code); + params.put("ordersuccesstime",ordersuccesstime); + params.put("err_msg",err_msg); + ofeiServer.checkOrderForNotify(params); + } +} \ No newline at end of file