Merge remote-tracking branch 'origin/develop' into develop

# Conflicts:
#	pay-java-demo/src/main/java/in/egan/pay/demo/dao/ApyAccountRepository.java
This commit is contained in:
zzs
2017-03-20 16:43:33 +08:00
9 changed files with 127 additions and 94 deletions

View File

@@ -12,16 +12,15 @@ import in.egan.pay.common.bean.PayOutMessage;
import in.egan.pay.common.bean.TransactionType;
import in.egan.pay.common.bean.result.PayException;
import in.egan.pay.common.exception.PayErrorException;
import in.egan.pay.common.http.ClientHttpRequest;
import in.egan.pay.common.http.HttpConfigStorage;
import in.egan.pay.common.http.UriVariables;
import in.egan.pay.common.util.MatrixToImageWriter;
import in.egan.pay.common.util.sign.SignUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.awt.image.BufferedImage;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -165,7 +164,7 @@ public class AliPayService extends BasePayService {
bizContent.put("scene", order.getTransactionType().toString().toLowerCase());
bizContent.put("product_code", "FACE_TO_FACE_PAYMENT");
bizContent.put("auth_code", order.getAuthCode());
}else {
}else if (order.getTransactionType() != AliTransactionType.SWEEPPAY){
bizContent.put("product_code", "QUICK_MSECURITY_PAY");
}
bizContent.put("body", order.getBody());
@@ -302,7 +301,7 @@ public class AliPayService extends BasePayService {
} else {
String biz_content = (String)orderInfo.remove("biz_content");
formHtml.append(getReqUrl()).append("?").append(ClientHttpRequest.getMapToParameters(orderInfo))
formHtml.append(getReqUrl()).append("?").append(UriVariables.getMapToParameters(orderInfo))
.append("\" method=\"")
.append(method.name().toLowerCase()).append("\">");
@@ -322,12 +321,24 @@ public class AliPayService extends BasePayService {
/**
* 生成二维码支付
* 暂未实现或无此功能
* @param orderInfo 发起支付的订单信息
* @param order 发起支付的订单信息
* @return
*/
@Override
public BufferedImage genQrPay(Map<String, Object> orderInfo) {
throw new UnsupportedOperationException();
public BufferedImage genQrPay(PayOrder order) {
Map<String, Object> orderInfo = orderInfo(order);
// Map<String, Object> content = new HashMap<>(1);
// content.put("biz_content", orderInfo.remove("biz_content"));
//预订单
JSONObject result = getHttpRequestTemplate().postForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(orderInfo), null, JSONObject.class);
JSONObject response = result.getJSONObject("alipay_trade_precreate_response");
if ("10000".equals(response.getString("code"))){
return MatrixToImageWriter.writeInfoToJpgBuff( response.getString("qr_code"));
}
throw new PayErrorException(new PayException(response.getString("code"), response.getString("msg"), result.toJSONString()));
}
/**
* 交易查询接口
@@ -399,7 +410,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}
@Override
@@ -457,7 +468,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}
/**
@@ -494,7 +505,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", getContentToJson(tradeNoOrBillDate.toString(), outTradeNoBillType));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(getReqUrl() + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}

View File

@@ -14,6 +14,7 @@ import in.egan.pay.common.bean.result.PayException;
import in.egan.pay.common.exception.PayErrorException;
import in.egan.pay.common.http.ClientHttpRequest;
import in.egan.pay.common.http.HttpConfigStorage;
import in.egan.pay.common.http.UriVariables;
import in.egan.pay.common.util.sign.SignUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -261,7 +262,7 @@ public class AliPayService extends BasePayService {
* @return
*/
@Override
public BufferedImage genQrPay(Map<String, Object> orderInfo) {
public BufferedImage genQrPay(PayOrder orderInfo) {
throw new UnsupportedOperationException();
}
@@ -336,7 +337,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}
@Override
public Map<String, Object> refundquery(String tradeNo, String outTradeNo) {
@@ -393,7 +394,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", JSON.toJSONString(bizContent));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}
/**
@@ -425,7 +426,7 @@ public class AliPayService extends BasePayService {
parameters.put("biz_content", getContentToJson(tradeNoOrBillDate.toString(), outTradeNoBillType));
//设置签名
setSign(parameters);
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + ClientHttpRequest.getMapToParameters(parameters), JSONObject.class));
return callback.perform(requestTemplate.getForObject(queryReqUrl + "?" + UriVariables.getMapToParameters(parameters), JSONObject.class));
}

View File

@@ -135,10 +135,10 @@ public interface PayService {
/**
* 获取输出二维码,用户返回给支付端,
*
* @param orderInfo 发起支付的订单信息
* @param order 发起支付的订单信息
* @return
*/
BufferedImage genQrPay(Map<String, Object> orderInfo);
BufferedImage genQrPay(PayOrder order);
/**
* 交易查询接口

View File

@@ -9,7 +9,7 @@ import in.egan.pay.common.bean.PayOutMessage;
* @email egzosn@gmail.com
* @date 2017/1/13 14:30
*/
public class JsonBuilder extends BaseBuilder<TextBuilder, PayOutMessage>{
public class JsonBuilder extends BaseBuilder<JsonBuilder, PayOutMessage>{
JSONObject json = null;
public JsonBuilder(JSONObject json) {

View File

@@ -24,6 +24,8 @@ import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import static in.egan.pay.common.http.UriVariables.getMapToParameters;
/**
* 一个HTTP请求的客户端
* @author: egan
@@ -94,48 +96,6 @@ public class ClientHttpRequest<T> extends HttpEntityEnclosingRequestBase impleme
return this;
}
/**
* Map转化为对应得参数字符串
* @param pe
* @return
*/
public static String getMapToParameters(Map pe){
StringBuilder builder = new StringBuilder();
for (Object key : pe.keySet()) {
Object o = pe.get(key);
if (null == o) {
continue;
}
if (o instanceof List) {
o = ((List) o).toArray();
}
try {
if (o instanceof Object[]) {
Object[] os = (Object[]) o;
String valueStr = "";
for (int i = 0, len = os.length; i < len; i++) {
if (null == os[i]) {
continue;
}
String value = os[i].toString().trim();
valueStr += (i == len - 1) ? value : value + ",";
}
builder.append(key).append("=").append(URLEncoder.encode(valueStr, "utf-8")).append("&");
continue;
}
builder.append(key).append("=").append(URLEncoder.encode((String) pe.get(key), "utf-8")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (builder.length() > 1) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
/**
* 设置请求参数

View File

@@ -1,6 +1,14 @@
package in.egan.pay.common.http;
import com.alibaba.fastjson.JSON;
import org.apache.http.Consts;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -39,6 +47,8 @@ public class UriVariables {
return uri;
}
/**
* 匹配Map.key
* @param uri
@@ -70,4 +80,51 @@ public class UriVariables {
}
/**
* Map转化为对应得参数字符串
* @param pe
* @return
*/
public static String getMapToParameters(Map pe){
StringBuilder builder = new StringBuilder();
for (Object key : pe.keySet()) {
Object o = pe.get(key);
if (null == o) {
continue;
}
if (o instanceof List) {
o = ((List) o).toArray();
}
try {
if (o instanceof Object[]) {
Object[] os = (Object[]) o;
String valueStr = "";
for (int i = 0, len = os.length; i < len; i++) {
if (null == os[i]) {
continue;
}
String value = os[i].toString().trim();
valueStr += (i == len - 1) ? value : value + ",";
}
builder.append(key).append("=").append(URLEncoder.encode(valueStr, "utf-8")).append("&");
continue;
}
builder.append(key).append("=").append(URLEncoder.encode((String) pe.get(key), "utf-8")).append("&");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
if (builder.length() > 1) {
builder.deleteCharAt(builder.length() - 1);
}
return builder.toString();
}
}

View File

@@ -2,7 +2,6 @@
package in.egan.pay.demo.controller;
import in.egan.pay.common.api.Callback;
import in.egan.pay.common.bean.*;
import in.egan.pay.common.util.str.StringUtils;
@@ -30,13 +29,14 @@ import static in.egan.pay.demo.dao.ApyAccountRepository.apyAccounts;
/**
* 发起支付入口
*
* @author: egan
* @email egzosn@gmail.com
* @date 2016/11/18 0:25
*/
@RestController
@RequestMapping
public class PayController{
public class PayController {
@Resource
private ApyAccountService service;
@@ -44,11 +44,12 @@ public class PayController{
/**
* 这里模拟账户信息增加
*
* @param account
* @return
*/
@RequestMapping("add")
public Map<String, Object> add(ApyAccount account){
public Map<String, Object> add(ApyAccount account) {
apyAccounts.put(account.getPayId(), account);
Map<String, Object> data = new HashMap<>();
data.put("code", 0);
@@ -62,68 +63,66 @@ public class PayController{
* 跳到支付页面
* 针对实时支付,即时付款
*
* @param payId 账户id
* @param payId 账户id
* @param transactionType 交易类型, 这个针对于每一个 支付类型的对应的几种交易方式
* @param bankType 针对刷卡支付,卡的类型,类型值
* @param bankType 针对刷卡支付,卡的类型,类型值
* @return
*/
@RequestMapping(value = "toPay.html", produces = "text/html;charset=UTF-8")
public String toPay( Integer payId, String transactionType, String bankType, BigDecimal price) {
public String toPay(Integer payId, String transactionType, String bankType, BigDecimal price) {
//获取对应的支付账户操作工具可根据账户id
PayResponse payResponse = service.getPayResponse(payId);
PayResponse payResponse = service.getPayResponse(payId);
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
//此处只有刷卡支付(银行卡支付)时需要
if (StringUtils.isNotEmpty(bankType)){
if (StringUtils.isNotEmpty(bankType)) {
order.setBankType(bankType);
}
Map orderInfo = payResponse.getService().orderInfo(order);
return payResponse.getService().buildRequest(orderInfo, MethodType.POST);
return payResponse.getService().buildRequest(orderInfo, MethodType.POST);
}
/**
* 获取二维码图像
* 二维码支付
*
* @return
*/
@RequestMapping(value = "toQrPay.jpg", produces = "image/jpeg;charset=UTF-8")
public byte[] toWxQrPay(Integer payId, String transactionType, BigDecimal price) throws IOException {
public byte[] toWxQrPay(Integer payId, String transactionType, BigDecimal price) throws IOException {
//获取对应的支付账户操作工具可根据账户id
PayResponse payResponse = service.getPayResponse(payId);
//获取订单信息
Map<String, Object> orderInfo = payResponse.getService().orderInfo(new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType)));
PayResponse payResponse = service.getPayResponse(payId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(payResponse.getService().genQrPay(orderInfo), "JPEG", baos);
ImageIO.write(payResponse.getService().genQrPay(new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, "9d1c43152c304ed2b9d2db320ef0a742", PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType))), "JPEG", baos);
return baos.toByteArray();
}
/**
* 获取支付预订单信息
*
* 获取支付预订单信息
* @param payId 支付账户id
* @param payId 支付账户id
* @param transactionType 交易类型
* @return
*/
@RequestMapping("getOrderInfo")
public Map<String, Object> getOrderInfo(Integer payId, String transactionType, BigDecimal price){
public Map<String, Object> getOrderInfo(Integer payId, String transactionType, BigDecimal price) {
//获取对应的支付账户操作工具可根据账户id
PayResponse payResponse = service.getPayResponse(payId);
PayResponse payResponse = service.getPayResponse(payId);
Map<String, Object> data = new HashMap<>();
data.put("code", 0);
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
data.put("orderInfo", payResponse.getService().orderInfo(order));
PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType));
data.put("orderInfo", payResponse.getService().orderInfo(order));
return data;
}
/**
* 微信或者支付宝回调地址
*
* @param request
* @return
*/
@@ -134,22 +133,23 @@ public class PayController{
PayConfigStorage storage = payResponse.getStorage();
//获取支付方返回的对应参数
Map<String, String> params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream());
if (null == params){
return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
if (null == params) {
return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
}
//校验
if (payResponse.getService().verify(params)){
if (payResponse.getService().verify(params)) {
PayMessage message = new PayMessage(params, storage.getPayType(), storage.getMsgType().name());
PayOutMessage outMessage = payResponse.getRouter().route(message);
return outMessage.toMessage();
}
return payResponse.getService().getPayOutMessage("fail","失败").toMessage();
return payResponse.getService().getPayOutMessage("fail", "失败").toMessage();
}
/**
* 查询
*
* @param order 订单的请求体
* @return
*/
@@ -158,8 +158,10 @@ public class PayController{
PayResponse payResponse = service.getPayResponse(order.getPayId());
return payResponse.getService().query(order.getTradeNo(), order.getOutTradeNo());
}
/**
* 交易关闭接口
*
* @param order 订单的请求体
* @return
*/
@@ -171,6 +173,7 @@ public class PayController{
/**
* 申请退款接口
*
* @param order 订单的请求体
* @return
*/
@@ -184,6 +187,7 @@ public class PayController{
/**
* 查询退款
*
* @param order 订单的请求体
* @return
*/
@@ -195,6 +199,7 @@ public class PayController{
/**
* 下载对账单
*
* @param order 订单的请求体
* @return
*/
@@ -208,8 +213,8 @@ public class PayController{
/**
* 通用查询接口,根据 TransactionType 类型进行实现,此接口不包括退款
* @param order 订单的请求体
*
* @param order 订单的请求体
* @return
*/
@RequestMapping("secondaryInterface")
@@ -225,7 +230,4 @@ public class PayController{
}
}

View File

@@ -362,7 +362,8 @@ public class WxYouDianPayService extends BasePayService {
}
@Override
public BufferedImage genQrPay(Map<String, Object> orderInfo) {
public BufferedImage genQrPay(PayOrder order) {
JSONObject orderInfo = orderInfo(order);
return MatrixToImageWriter.writeInfoToJpgBuff((String) orderInfo.get("code_url"));
}

View File

@@ -242,7 +242,8 @@ public class WxPayService extends BasePayService {
}
@Override
public BufferedImage genQrPay(Map<String, Object> orderInfo) {
public BufferedImage genQrPay(PayOrder order) {
Map<String, Object> orderInfo = orderInfo(order);
//获取对应的支付账户操作工具可根据账户id
if (!"SUCCESS".equals(orderInfo.get("result_code"))) {
throw new PayErrorException(new WxPayError("-1", (String) orderInfo.get("err_code")));