包名修改

This commit is contained in:
zzs
2017-04-10 09:22:17 +08:00
parent 174f602dd7
commit 7152f001e4
100 changed files with 564 additions and 515 deletions

View File

@@ -0,0 +1,19 @@
package com.egzosn.pay.fuiou;/**
* Created by Fuzx on 2017/2/10 0010.
*/
import com.egzosn.pay.common.util.sign.SignUtils;
/**
* @author Fuzx
* @create 2017 2017/2/10 0010
*/
public class Test {
public static void main(String[] args) {
String content="0002230F0348879|17021013591343700615|805a9aphsvmbf6qih8k66vu1svafj99m";
System.out.println(SignUtils.valueOf("MD5").createSign(content, "", "UTF-8"));
}
}

View File

@@ -0,0 +1,44 @@
package com.egzosn.pay.fuiou.api;/**
* Created by Fuzx on 2017/1/16 0016.
*/
import com.egzosn.pay.common.before.api.BasePayConfigStorage;
/**
* @author Fuzx
* @create 2017 2017/1/16 0016
*/
public class FuiouPayConfigStorage extends BasePayConfigStorage {
public String mchntCd;//商户代码
public String mchntKey;//商户密钥
@Override
public String getAppid() {
return null;
}
@Override
public String getPartner() {
return mchntCd;
}
public void setPartner(String partner) {
this.mchntCd = partner;
}
@Override
public String getSeller() {
return null;
}
@Override
public String getSecretKey() {
return mchntKey;
}
public void setSecretKey(String mchntKey){
this.mchntKey = mchntKey;
}
}

View File

@@ -0,0 +1,301 @@
package com.egzosn.pay.fuiou.api;/**
* Created by Fuzx on 2017/1/16 0016.
*/
import com.egzosn.pay.common.before.api.BasePayService;
import com.egzosn.pay.common.before.api.PayConfigStorage;
import com.egzosn.pay.common.before.api.RequestExecutor;
import com.egzosn.pay.common.bean.MethodType;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.before.bean.result.PayError;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.util.sign.SignUtils;
import com.egzosn.pay.common.util.str.StringUtils;
import com.egzosn.pay.fuiou.utils.SimplePostRequestExecutor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.message.BasicNameValuePair;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.util.*;
/**
* @author Fuzx
* @create 2017 2017/1/16 0016
*/
public class FuiouPayService extends BasePayService {
protected final Log log = LogFactory.getLog(FuiouPayService.class);
public final static String fuiouBaseDomain = "https://pay.fuiou.com/";//正式域名
// public final static String fuiouBaseDomain = "http://www-1.fuiou.com:8888/wg1_run/";//测试域名
public final static String fuiouSmpGate = fuiouBaseDomain + "smpGate.do";//B2C/B2B支付
public final static String fuiouNewSmpGate = fuiouBaseDomain + "newSmpGate.do";//B2C/B2B支付(跨境支付)
public final static String fuiouSmpRefundGate = fuiouBaseDomain + "newSmpRefundGate.do";//订单退款
public final static String fuiouSmpQueryGate = fuiouBaseDomain + "smpQueryGate.do";//3.2 支付结果查询
public final static String fuiouSmpAQueryGate = fuiouBaseDomain + "smpAQueryGate.do";//3.3 支付结果查询(直接返回)
public FuiouPayService(PayConfigStorage payConfigStorage) {
setPayConfigStorage(payConfigStorage);
}
@Override
public String getHttpsVerifyUrl() {
return null;
}
/**
* 回调校验
* @param params 回调回来的参数集
* @return
*/
@Override
public boolean verify(Map<String, String> params) {
if (!"0000".equals(params.get("order_pay_code"))) {
log.debug(String.format("富友支付异常order_pay_code=%s,错误原因=%s,参数集=%s", params.get("order_pay_code"), params.get("order_pay_error"), params));
return false;
}
try {
return getSignVerify(params, params.get("md5")) && "0000".equals(verifyUrl(params.get("order_id")));//返回参数校验 和 重新请求订单检查数据是否合法
} catch (PayErrorException e) {
e.printStackTrace();
}
return false;
}
/**
* 校验回调参数是否合法
* @param params 参数集
* @param returnSign
* @return
*/
@Override
public boolean getSignVerify(Map<String, String> params, String returnSign) {
LinkedHashSet<String> keySet = new LinkedHashSet<>();
keySet.add("mchnt_cd");//商户代码
keySet.add("order_id");//商户订单号
keySet.add("order_date");//订单日期
keySet.add("order_amt");//交易金额
keySet.add("order_st");//订单状态
keySet.add("order_pay_code");//错误代码
keySet.add("order_pay_error");//错误中文描述
keySet.add("resv1");//保留字段
keySet.add("fy_ssn");//富友流水号
StringBuilder verifyMD5Str = new StringBuilder();
for (String keyStr : keySet) {
String keyValue = params.get(keyStr);
if (null == keyValue){
log.debug(String.format("富友支付返回结果校验:<参数:%s>不能为空,",keyStr));
}
verifyMD5Str.append(keyValue).append("|");
}
String sign = createSign(verifyMD5Str.deleteCharAt(verifyMD5Str.length() -1).toString(),payConfigStorage.getInputCharset());
// System.out.println("加密串"+verifyMD5Str+",,返回参数生成MD5="+sign+",,返回MD5摘要值"+returnSign);
if(returnSign.equals(sign)){
return true;
}
return false;
}
/**
* 发起请求校验订单是否支付成功
* @param order_id
* @return
* @throws PayErrorException
*/
@Override
public String verifyUrl(String order_id) throws PayErrorException {
// LinkedHashMap param = new LinkedHashMap();
// param.put("mchnt_cd",payConfigStorage.getPartner());
// param.put("order_id",order_id);
// param.put("md5",createSign(SignUtils.parameters2MD5Str(param,"|"),payConfigStorage.getInputCharset()));
List<BasicNameValuePair> pairList = new ArrayList<BasicNameValuePair>();
pairList.add(new BasicNameValuePair("mchnt_cd",payConfigStorage.getPartner()));
pairList.add(new BasicNameValuePair("order_id",order_id));
pairList.add(new BasicNameValuePair("md5",createSign(SignUtils.parameters2MD5Str(pairList,"|"),payConfigStorage.getInputCharset())));
return execute(new SimplePostRequestExecutor(), fuiouSmpAQueryGate,pairList);
// JSONObject jsonObject = XML.toJSONObject(responseContent);
// return getFormString(param,MethodType.POST,fuiouSmpAQueryGate);
}
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws PayErrorException {
int retryTimes = 0;
do {
try {
return executeInternal(executor, uri, data);
} catch (PayErrorException e) {
PayError error = (PayError) e.getPayError();
if ("404".equals(error.getErrorCode()) ) {
int sleepMillis = retrySleepMillis * (1 << retryTimes);
try {
log.debug(String.format("富友支付系统错误,错误信息:<%s>,(%s)ms 后重试(第%s次)",e.getMessage(),sleepMillis, retryTimes + 1));
Thread.sleep(sleepMillis);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
} else {
throw e;
}
}
} while (++retryTimes < maxRetryTimes);
throw new RuntimeException("富友支付服务端异常,超出重试次数");
}
/**
* 对支付请求参数进行加密,排序
* @param order 支付订单
* @return
*/
@Override
public Map<String, Object> orderInfo(PayOrder order) {
LinkedHashMap<String, Object> parameters = getOrderInfo(order);
String sign = createSign(SignUtils.parameters2MD5Str(parameters, "|"), payConfigStorage.getInputCharset());
parameters.put("md5", sign);
return parameters;
}
private LinkedHashMap<String, Object> getOrderInfo(PayOrder order) {
LinkedHashMap<String, Object> parameters = new LinkedHashMap<String, Object>();
parameters.put("mchnt_cd", payConfigStorage.getPartner());//商户代码
parameters.put("order_id", order.getTradeNo());//商户订单号
parameters.put("order_amt", order.getPrice());//交易金额
// parameters.put("cur_type", null == order.getCurType() ? FuiouCurType.CNY:order.getCurType());//交易币种
parameters.put("order_pay_type", order.getTransactionType());//支付类型
parameters.put("page_notify_url", payConfigStorage.getReturnUrl());//商户接受支付结果通知地址
parameters.put("back_notify_url", StringUtils.isBlank(payConfigStorage.getNotifyUrl()) ? "" : payConfigStorage.getNotifyUrl());//商户接受的支付结果后台通知地址 //非必填
parameters.put("order_valid_time", "30m");//超时时间 1m-15天m分钟、h小时、d天、1c当天有效
parameters.put("iss_ins_cd", order.getBankType());//银行代码
parameters.put("goods_name", order.getSubject());
parameters.put("goods_display_url", "1");//商品展示网址 //非必填
parameters.put("rem", "1");//备注 //非必填
parameters.put("ver", "1.0.1");//版本号
return parameters;
}
/**
* 对内容进行加密
* @param content 需要签名的内容
* @param characterEncoding 字符编码
* @return
*/
@Override
public String createSign(String content, String characterEncoding) {
return SignUtils.valueOf(payConfigStorage.getSignType().toUpperCase()).createSign(content, "|" + payConfigStorage.getSecretKey(), characterEncoding);
}
/**
* 将参数拼凑成String
* @param parameterMap 请求参数
* @param is 请求流
* @return
*/
@Override
public Map<String, String> getParameter2Map(Map<String, String[]> parameterMap, InputStream is) {
Map<String, String> params = new TreeMap<String, String>();
for (Iterator iter = parameterMap.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
String[] values = parameterMap.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
return params;
}
@Override
public PayOutMessage getPayOutMessage(String code, String message) {
return PayOutMessage.TEXT().content(code.toLowerCase()).build();
}
@Override
public String buildRequest(Map<String, Object> orderInfo, MethodType method) {
return getFormString(orderInfo, method,fuiouSmpGate);
}
/**
* 根据参数行程form表单
* @param param 参数
* @param method 请求方式 get_post
* @param url
* @return
*/
private String getFormString(Map<String, Object> param, MethodType method,String url) {
StringBuffer formHtml = new StringBuffer();
formHtml.append("<form id=\"fuiousubmit\" name=\"fuiousubmit\" action=\"")
.append(url)
.append("\" accept-charset=\"UTF-8\" onsubmit=\"document.charset='UTF-8';")
// .append( payConfigStorage.getInputCharset())
.append("\" method=\"")
.append(method.name().toLowerCase()).append("\">");
for (String key : param.keySet()) {
Object o = param.get(key);
if (null == o || "null".equals(o) || "".equals(o)) {
continue;
}
formHtml.append("<input type=\"hidden\" name=\"" + key + "\" value=\"" + param.get(key) + "\"/>");
}
//submit按钮控件请不要含有name属性
// formHtml.append("<input type=\"submit\" value=\"\" style=\"display:none;\">");
formHtml.append("</form>");
formHtml.append("<script>document.forms['fuiousubmit'].submit();</script>");
return formHtml.toString();
}
/**
* 生成二维码支付
* 暂未实现或无此功能
*
* @param orderInfo 发起支付的订单信息
* @return
*/
@Override
public BufferedImage genQrPay(Map<String, Object> orderInfo) {
throw new UnsupportedOperationException();
}
@Override
public Map<String, Object> query(String tradeNo, String outTradeNo) {
return null;
}
@Override
public Map<String, Object> close(String tradeNo, String outTradeNo) {
return null;
}
@Override
public Map<String, Object> refund(String tradeNo, String outTradeNo) {
return null;
}
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
return null;
}
@Override
public Object downloadbill(Date billDate, String billType) {
return null;
}
}

View File

@@ -0,0 +1,35 @@
package com.egzosn.pay.fuiou.bean;/**
* Created by Fuzx on 2017/1/24 0024.
*/
import com.egzosn.pay.common.bean.CurType;
/**
* @author Fuzx
* @create 2017 2017/1/24 0024
*/
public enum FuiouCurType implements CurType {
CNY("人民币"),
USD("美元"),
HKD("港币"),
MOP("澳门元"),
EUR("欧元"),
TWD("新台币"),
KRW("韩元"),
JPY("日元"),
SGD("新加坡元"),
AUD("澳大利亚元");
private String name;
private int index;
private FuiouCurType(String name) {
this.name = name;
}
@Override
public String getCurType(){
return this.name();
}
}

View File

@@ -0,0 +1,35 @@
package com.egzosn.pay.fuiou.bean;
import com.egzosn.pay.common.bean.TransactionType;
/**
* 微信交易类型
* @author egan
* @email egzosn@gmail.com
* @date 2016/10/19 22:58
*/
public enum FuiouTransactionType implements TransactionType {
B2B(""),
B2C("")
;
private String method;
private FuiouTransactionType(String method) {
this.method = method;
}
@Override
public String getType() {
return this.name();
}
/**
* 获取接口名称
* @return
*/
@Override
public String getMethod() {
return this.method;
}
}

View File

@@ -0,0 +1,76 @@
package com.egzosn.pay.fuiou.utils;
import com.alibaba.fastjson.JSONObject;
import com.egzosn.pay.common.before.api.RequestExecutor;
import com.egzosn.pay.common.before.bean.result.PayError;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.common.util.XML;
import com.egzosn.pay.common.before.util.http.Utf8ResponseHandler;
import org.apache.http.Consts;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author egan
* @email egzosn@gmail.com
* @date 2016-5-18 14:09:01
*/
public class SimplePostRequestExecutor implements RequestExecutor<String, Object> {
@Override
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, Object postEntity) throws PayErrorException, ClientProtocolException, IOException {
HttpPost httpPost = new HttpPost(uri);
// httpPost.setHeader("Content-Type","application/x-www-from-urlencoded");
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
httpPost.setConfig(config);
}
if (postEntity instanceof Map) {
StringBuilder builder = new StringBuilder();
Map pe = (Map) postEntity;
for (Object key : pe.keySet()) {
builder.append(key).append("=").append(pe.get(key)).append("&");
}
if (builder.length() > 1) {
builder.deleteCharAt(builder.length() - 1);
}
StringEntity entity = new StringEntity(builder.toString(), Consts.UTF_8);
// entity.setContentType("application/x-www-from-urlencoded");
httpPost.setEntity(entity);
} else if (postEntity instanceof String) {
StringEntity entity = new StringEntity((String) postEntity, Consts.UTF_8);
httpPost.setEntity(entity);
}else if(postEntity instanceof List){
//表单方式
httpPost.setEntity(new UrlEncodedFormEntity((List<BasicNameValuePair>)postEntity, Consts.UTF_8));
}
try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
// System.out.println("直接返回的查询结果-->"+responseContent);
// responseContent = responseContent.replace("<ap>","").replace("</ap>","").replace("<plain>","").replace("</plain>","");
JSONObject jsonObject = XML.toJSONObject(responseContent);//包含md5
JSONObject plain = XML.toJSONObject("<a>"+jsonObject.getString("plain")+"</a>");//"plain" -> "<order_pay_code>5002</order_pay_code><order_pay_error>验证签名失败</order_pay_error><order_id></order_id><order_st></order_st><fy_ssn></fy_ssn><resv1></resv1>"
if("0000".equals(plain.getString("order_pay_code"))){
return "0000";
}else{
throw new PayErrorException(new PayError(404,plain.getString("order_pay_error"),responseContent));
}
}finally {
httpPost.releaseConnection();
}
}
}