Authored by tanling

支付接口提供

Showing 32 changed files with 851 additions and 58 deletions
package com.yohoufo.common.utils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
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.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class HttpClient {
private Logger logger = LoggerFactory.getLogger(getClass());
protected static final int connectionRequestTimeout = 6000;
protected static final int connectionTimeout = 3000;
protected static final int socketTimeout = 2000;
//最大总数
private final int maxTotal = 30;
//默认并发数
private final int defaultMaxPerRoute = 10;
protected CloseableHttpClient httpClient;
@PostConstruct
public void init() throws Exception{
HttpClientBuilder b = HttpClientBuilder.create();
// setup a Trust Strategy that allows all certificates.
//
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] arg0, String arg1)
throws CertificateException {
return true;
}
}).build();
b.setSSLContext(sslContext);
// don't check Hostnames, either.
// -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if
// you don't want to weaken
HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
// here's the special part:
// -- need to create an SSL Socket Factory, to use our weakened
// "trust strategy";
// -- and create a Registry, to register it.
//
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http",
PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslSocketFactory).build();
// now, we create connection-manager using our Registry.
// -- allows multi-threaded use
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager(
socketFactoryRegistry);
connMgr.setMaxTotal(maxTotal);
connMgr.setDefaultMaxPerRoute(defaultMaxPerRoute);
b.setConnectionManager(connMgr);
//request config
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(connectionRequestTimeout)
.setConnectTimeout(connectionTimeout)
.setSocketTimeout(socketTimeout)
.build();
b.setDefaultRequestConfig(requestConfig);
// finally, build the HttpClient;
// -- done!
httpClient = b.build();
}
public void destroy() {
if(httpClient != null)
httpClient.getConnectionManager().shutdown();
}
/**
* Get请求
* @param url
* @return
* @throws Exception
*/
public String get(String url) throws Exception {
HttpGet httpget = new HttpGet(url);
return sendHttpRequest(httpget);
}
/**
* Post请求
* @param url
* @param body
* @return
* @throws Exception
*/
public String post(String url, String body) throws Exception {
HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Content-Type", "application/json;charset=UTF-8");
httpPost.setEntity(new StringEntity(body, "UTF-8"));
return sendHttpRequest(httpPost);
}
/**
* 提交form-data
* @param url
* @param formDataMap
* @return
* @throws Exception
*/
public String postFormData(String url, Map<String, String> formDataMap) throws Exception {
HttpPost httpPost = new HttpPost(url);
//httpPost.addHeader("Content-Type", "multipart/form-data;charset=UTF-8");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
if(formDataMap != null) {
for(Map.Entry<String, String> data : formDataMap.entrySet()) {
nvps.add(new BasicNameValuePair(data.getKey(), data.getValue()));
}
}
httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
return sendHttpRequest(httpPost);
}
/**
* http发送请求
* @param httpRequest
* @return
* @throws Exception
*/
private String sendHttpRequest(HttpUriRequest httpRequest) throws Exception {
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpRequest);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
logger.error("http response code: {}, request: {}", statusCode, httpRequest.getURI());
throw new RuntimeException("http response status: " + statusCode);
}
return EntityUtils.toString(response.getEntity(), "UTF-8");
}
finally {
if (response != null) {
try {
response.close();
} catch (Exception e) {
logger.error("pay httpclient resp close failed: {}", e.getMessage());
}
}
if(httpRequest != null) {
try {
httpRequest.abort();
} catch (Exception e) {
logger.error("pay httpclient req abort failed: {}", e.getMessage());
}
}
}
}
}
... ...
package com.yohoufo.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.yoho.core.common.utils.MD5;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class SignUtils {
/**
* 获取签名
* @param data
* @param signKey
* @return
*/
public static String getSign(JSONObject data, String signKey){
List<String> list = Lists.newArrayList();
for (String str: data.keySet()){
list.add(str+"="+data.getString(str));
}
Collections.sort(list);
String param = list.stream().collect(Collectors.joining("&"));
String sign = MD5.md5(param+signKey);
return sign;
}
}
... ...
package com.yohoufo.dal.order;
import com.yohoufo.dal.order.model.BuyerOrder;
import org.apache.ibatis.annotations.Param;
public interface BuyerOrderMapper {
int deleteByPrimaryKey(Integer id);
... ... @@ -11,6 +13,8 @@ public interface BuyerOrderMapper {
BuyerOrder selectByPrimaryKey(Integer id);
BuyerOrder selectByOrderCode(@Param("orderCode") Long orderCode);
int updateByPrimaryKeySelective(BuyerOrder record);
int updateByPrimaryKey(BuyerOrder record);
... ...
... ... @@ -12,6 +12,7 @@ public interface SellerOrderMapper {
SellerOrder selectByPrimaryKey(Integer id);
SellerOrder selectByOrderCode(@Param("orderCode") long orderCode);
SellerOrder selectBySkup(@Param("skup") Integer skup);
... ...
... ... @@ -22,12 +22,25 @@
id, uid, order_code, seller_uid, client_type, payment, payment_type, is_cancel, amount,
ship_fee, status, create_time, update_time, order_status, channel_no
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectByOrderCode" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from buyer_order
where order_code = #{orderCode,jdbcType=BIGINT}
limit 1
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
delete from buyer_order
where id = #{id,jdbcType=INTEGER}
... ...
... ... @@ -26,6 +26,15 @@
where id = #{id,jdbcType=INTEGER}
</select>
<select id="selectByOrderCode" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from seller_order
where order_code = #{orderCode,jdbcType=BIGINT}
limit 1
</select>
<select id="selectBySkup" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
... ...
package com.yohoufo.order.common;
public enum OrderCodeType {
SELLER_TYPE(0l),
BUYER_TYPE(1l);
long type;
OrderCodeType(long type) {
this.type = type;
}
public long getType() {
return type;
}
/**
* 订单号的类型
* @param code
* @return
*/
public static boolean isExistOrderCodeType(long code){
for(OrderCodeType v : values()){
if(v.type == code){
return true;
}
}
return false;
}
}
... ...
package com.yohoufo.order.common;
public enum Payment {
ALIPAY(1, "trade.precreate"),
WECHAT(2, "wx.unifiedOrder");
int code;
/**
* 银联接口请求值
*/
String value;
Payment(int code, String value) {
this.code = code;
this.value = value;
}
public int getCode() {
return code;
}
public String getValue() {
return value;
}
/**
* 检查是否存在该支付方式
* @param code
* @return
*/
public static Payment getPayment(int code){
for(Payment v : values()){
if(v.code == code){
return v;
}
}
return null;
}
}
... ...
... ... @@ -32,5 +32,12 @@ public interface OrderConstant {
String Y_STR= "Y";
String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
/**
* 调用银联接口,商户订单号 以银联分配的4位系统编号作为订单号的前四位
*/
String ORDER_CODE_PRE = "3194";
}
... ...
package com.yohoufo.order.controller;
import com.yohoufo.common.ApiResponse;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import com.yohoufo.order.service.IPaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/payment")
public class PaymentController {
@Autowired
IPaymentService paymentService;
/**
* 订单支付
* @return
*/
@RequestMapping(params = "method=ufo.order.pay")
public ApiResponse pay(@RequestParam(name = "uid") int uid,
@RequestParam(name = "orderCode") long orderCode,
@RequestParam(name = "payment") int payment){
PaymentRequest request = PaymentRequest.builder().uid(uid).orderCode(orderCode).payment(payment).build();
PrepayResponse paymentResponse = paymentService.payment(request);
if (paymentResponse.getPrepayResult() == PrepayResponse.FAILED){
return new ApiResponse.ApiResponseBuilder().code(PrepayResponse.FAILED).data(paymentResponse.getJsonObj()).message("支付订单失败").build();
}else{
return new ApiResponse.ApiResponseBuilder().code(PrepayResponse.SUCCESS).data(paymentResponse.getJsonObj()).message("支付订单成功").build();
}
}
}
... ...
... ... @@ -7,13 +7,9 @@ import com.yohoufo.order.response.OrderSubmitResponse;
import com.yohoufo.order.response.ShoppingPaymentResponse;
import com.yohoufo.order.service.IShoppingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
@Controller
@RestController
@RequestMapping(value = "/shopping")
public class ShoppingController {
... ... @@ -26,7 +22,7 @@ public class ShoppingController {
* 结算
* @return
*/
@RequestMapping(params = "params=ufo.order.payment")
@RequestMapping(params = "method=ufo.order.payment")
public ApiResponse payment(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup){
... ... @@ -39,7 +35,7 @@ public class ShoppingController {
* 提交订单成功
* @return
*/
@RequestMapping(params = "params=ufo.order.submit")
@RequestMapping(params = "method=ufo.order.submit")
public ApiResponse submit(@RequestParam(name = "uid") int uid,
@RequestParam(name = "skup") int skup,
@RequestParam(name = "channelNo") String channelNo,
... ... @@ -55,4 +51,6 @@ public class ShoppingController {
}
... ...
package com.yohoufo.order.request;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Builder;
import java.math.BigDecimal;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PaymentRequest {
private int uid;
private long orderCode;
private int payment;
}
... ...
package com.yohoufo.order.response;
import com.alibaba.fastjson.JSONObject;
public class PrepayResponse {
public static final int SUCCESS = 200;
public static final int FAILED = 501;
private int prepayResult = FAILED;
private JSONObject jsonObj = new JSONObject();
public int getPrepayResult() {
return prepayResult;
}
public void setPrepayResult(int prepayResult) {
this.prepayResult = prepayResult;
}
public JSONObject getJsonObj() {
return jsonObj;
}
public void setJsonObj(JSONObject jsonObj) {
this.jsonObj = jsonObj;
}
}
\ No newline at end of file
... ...
package com.yohoufo.order.service;
import com.yohoufo.order.model.dto.OrderBuilder;
import org.springframework.transaction.annotation.Transactional;
public interface IOrdeCreationService {
... ...
package com.yohoufo.order.service;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
public interface IPaymentService {
/**
* 支付
* @param request
* @return
*/
public PrepayResponse payment(PaymentRequest request);
}
... ...
... ... @@ -92,14 +92,14 @@ public class SellerOrderService {
//createSkup()
//TODO step 2: create order, set status(not pay)
//TODO generate a new real code
long orderCode = new OrderCodeGenerator(){
@Override
public long generate() {
return new Random(10000000).nextLong();
}
}.generate();
// long orderCode = new OrderCodeGenerator(){
// @Override
// public long generate() {
// return new Random(10000000).nextLong();
// }
// }.generate();
//createOrder()
return orderCode;
return null;
}
... ...
package com.yohoufo.order.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.common.utils.DateUtil;
import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohoufo.common.utils.HttpClient;
import com.yohoufo.common.utils.SignUtils;
import com.yohoufo.dal.order.BuyerOrderMapper;
import com.yohoufo.dal.order.SellerOrderMapper;
import com.yohoufo.dal.order.model.BuyerOrder;
import com.yohoufo.dal.order.model.SellerOrder;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.OrderStatus;
import com.yohoufo.order.common.Payment;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.request.PaymentRequest;
import com.yohoufo.order.response.PrepayResponse;
import com.yohoufo.order.service.IPaymentService;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.Date;
@Service
public class PaymentServiceImpl implements IPaymentService {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
BuyerOrderMapper buyerOrderMapper;
@Autowired
SellerOrderMapper sellerOrderMapper;
@Value("${unionpay.pay.url}")
private String unionPayUrl;
@Value("${unionpay.pay.callbackUrl}")
private String callbackUrl;
@Value("${unionpay.pay.msgSrc}")
private String msgSrc;
@Value("${unionpay.pay.mid}")
private String mid;
@Value("${unionpay.pay.tid}")
private String tid;
@Value("${unionPay.pay.signKey}")
private String signKey;
@Autowired
HttpClient httpClient;
/**
* 机构商户号
*/
public static final String INST_MID = "APPDEFAULT";
@Autowired
OrderCodeGenerator orderCodeGenerator;
/**
* 支付
* @param request
* @return
*/
public PrepayResponse payment(PaymentRequest request){
// 入口数据检查
if (request.getUid() < 0
|| request.getOrderCode() < 0){
logger.warn("payment not exist");
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// 不存在的支付方式
Payment payment = Payment.getPayment(request.getPayment());
if (payment == null){
logger.warn("payment payment not exist {}, uid is {}, orderCode is {}" ,request.getPayment(),
request.getUid(), request.getOrderCode());
throw new ServiceException(ServiceError.ORDER_PAYMENT_IS_EMPTY);
}
// 卖家or买家订单,支付方式更新,返回实付金额
BigDecimal amount = checkUpdOrderCode(request);
// 生成预支付数据
JSONObject prepayData = buildPrepayData(request, payment.getValue(), amount);
PrepayResponse response = new PrepayResponse();
try{
String result = httpClient.post(unionPayUrl, JSON.toJSONString(prepayData));
JSONObject resultJSON = JSONObject.parseObject(result);
if (resultJSON.containsKey("errCode") && "SUCCESS".equals(resultJSON.getString("errCode"))){
response.setPrepayResult(PrepayResponse.SUCCESS);
response.setJsonObj(resultJSON.getJSONObject("appPayRequest"));
logger.info("payment success orderCode is {}", request.getOrderCode() );
return response;
}else {
response.setPrepayResult(PrepayResponse.FAILED);
response.setJsonObj(resultJSON);
logger.warn("payment fail, orderCode is {}, result is {}", request.getOrderCode(), result);
return response;
}
}catch (Exception e) {
logger.warn("payment error orderCode is {}, e is {}", request.getOrderCode());
}
response.setPrepayResult(PrepayResponse.FAILED);
return response;
}
/**
* 生成预支付数据
* @param request
* @param paymentVal
* @return
*/
private JSONObject buildPrepayData(PaymentRequest request, String paymentVal, BigDecimal amount) {
JSONObject prepayData = new JSONObject();
prepayData.put("msgSrc", msgSrc);
prepayData.put("msgType", paymentVal);
prepayData.put("requestTimestamp", DateUtil.date2String(new Date(), OrderConstant.DATE_FORMAT));
prepayData.put("merOrderId", OrderConstant.ORDER_CODE_PRE + request.getOrderCode());
prepayData.put("mid", mid);
prepayData.put("tid", tid);
prepayData.put("instMid", INST_MID);
prepayData.put("notifyUrl", callbackUrl);
// 单位分 存在点,则签名失败,不支持1.0这种
prepayData.put("totalAmount", amount.multiply(new BigDecimal(100)).setScale( 0, BigDecimal.ROUND_DOWN ).longValue());
prepayData.put("sign", SignUtils.getSign(prepayData, signKey));
return prepayData;
}
private BigDecimal checkUpdOrderCode(PaymentRequest request) {
// 根据订单号 反解:买家订单号 or 卖家订单号
CodeMeta codeMeta = orderCodeGenerator.expId(request.getOrderCode());
if (!OrderCodeType.isExistOrderCodeType(codeMeta.getType())) {
logger.warn("payment orderCode invalidate {}, uid is {}, codeMeta is {}", request.getOrderCode(), request.getUid(), codeMeta.getType());
throw new ServiceException(ServiceError.ORDER_ORDER_CODE_IS_EMPTY);
}
logger.info("payment orderCode is {} ,uid is {}, type is {}",request.getOrderCode(), request.getUid(), codeMeta.getType());
// 卖家订单号
if (codeMeta.getType() == OrderCodeType.BUYER_TYPE.getType()){
return checkUpdBuyerOrderCode(request);
}else{
return checkUpdSellerOrderCode(request);
}
}
private BigDecimal checkUpdSellerOrderCode(PaymentRequest request) {
// 订单状态
SellerOrder sellerOrder = sellerOrderMapper.selectByOrderCode(request.getOrderCode());
if (sellerOrder == null){
logger.warn("payment orderCode not exist, orderCode is {}", request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_NULL);
}
// 订单不是未付款的状态
if (sellerOrder.getStatus() == null || sellerOrder.getStatus().intValue() != OrderStatus.WAITING_PAY.getCode()){
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", sellerOrder.getStatus(), request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
// 检查实付金额 TODO
// 更新预支付方式
sellerOrder.setPayment((byte)request.getPayment());
sellerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
sellerOrderMapper.updateByPrimaryKey(sellerOrder);
return sellerOrder.getIncome();
}
/**
* 检查买家订单状态,更新支付方式
* @param request
*/
private BigDecimal checkUpdBuyerOrderCode(PaymentRequest request) {
// 订单状态
BuyerOrder buyerOrder = buyerOrderMapper.selectByOrderCode(request.getOrderCode());
if (buyerOrder == null){
logger.warn("payment orderCode not exist, orderCode is {}", request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_NULL);
}
// 订单不是未付款的状态
if (buyerOrder.getStatus() == null || buyerOrder.getStatus().intValue() != OrderStatus.WAITING_PAY.getCode()){
logger.warn("payment status not allow {}, orderCode is {}, uid is {}", buyerOrder.getStatus(), request.getOrderCode(), request.getUid());
throw new ServiceException(ServiceError.ORDER_PAY_NOT_ALLOW);
}
// 检查实付金额 TODO
// 更新预支付方式
buyerOrder.setPayment((byte)request.getPayment());
buyerOrder.setUpdateTime(DateUtil.getCurrentTimeSecond());
buyerOrderMapper.updateByPrimaryKey(buyerOrder);
return buyerOrder.getAmount();
}
}
... ...
... ... @@ -4,6 +4,7 @@ import com.yoho.error.ServiceError;
import com.yoho.error.exception.ServiceException;
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
import com.yohoufo.dal.order.model.SellerOrderGoods;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.common.SkupStatus;
import com.yohoufo.order.constants.OrderConstant;
import com.yohoufo.order.model.dto.OrderBuilder;
... ... @@ -14,7 +15,6 @@ import com.yohoufo.order.service.IOrdeCreationService;
import com.yohoufo.order.service.IShoppingService;
import com.yohoufo.order.service.support.ShoppingSupport;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.OrderCodeType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -50,8 +50,7 @@ public class ShoppingServiceImpl implements IShoppingService{
// 入口参数检查
if (request.getSkup() < 0 || request.getUid() <0){
logger.warn("payment uid or skup is null");
// TODO
throw new ServiceException(ServiceError.ORDER_REQUEST_ERROR);
throw new ServiceException(ServiceError.ORDER_REQUEST_PARM_IS_EMPTY);
}
// skup是否是可售状态
... ...
package com.yohoufo.order.service.support.codegenerator;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
/**
... ...
package com.yohoufo.order.service.support.codegenerator;
public enum OrderCodeType {
SELLER_TYPE(0),
BUYER_TYPE(1);
int type;
OrderCodeType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
package com.yohoufo.order.service.support.codegenerator.impl;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
import com.yohoufo.order.service.support.codegenerator.OrderCodeType;
import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import com.yohoufo.order.service.support.codegenerator.converter.IdConverterHelper;
... ...
... ... @@ -2,7 +2,6 @@ package com.yohoufo.order.service.support.codegenerator.timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
public class SimpleTimer {
protected static final Logger log = LoggerFactory.getLogger(SimpleTimer.class);
... ...
package com.yoho.pay;
package com.yohoufo.order.service;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
... ...
package com.yoho.pay;
package com.yohoufo.order.service;
import com.yoho.core.common.utils.TimeUtils;
... ...
package com.yoho.pay;
package com.yohoufo.order.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
... ... @@ -20,6 +20,16 @@ public class PayTest {
public static final String url = "https://qr-test2.chinaums.com/netpay-route-server/api/";
@Test
public void test(){
BigDecimal bigDecimal = new BigDecimal(1.0);
System.out.println(bigDecimal.toPlainString());
}
/**
* 预支付=下单接口 支付宝
*/
... ... @@ -32,11 +42,11 @@ public class PayTest {
data.put("msgType", "trade.precreate"); // 微信:wx.unifiedOrder, 支付宝:trade.precreate, 全民付:qmf.order, 银联云闪付:uac.appOrder
data.put("requestTimestamp", DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 支付宝- 31945075157
data.put("merOrderId", "31942222222222");
data.put("merOrderId", "319422222222224444");
data.put("mid", "898310148160568"); //商户号 仅用于支付宝和云闪付
data.put("tid","00000001"); //终端号
data.put("instMid", "APPDEFAULT"); // 机构商户号
data.put("totalAmount", 1);
data.put("totalAmount", 1.0);
// 回调接口 http://api-test3.dev.yohocorp.com/payment/weixin_notify
data.put("notifyUrl", "http://testapi.yohops.com/payment/weixin_notify");
... ... @@ -44,6 +54,9 @@ public class PayTest {
data.put("sign", getSign(data));
String dataStr = "{\"totalAmount\":1.00,\"msgType\":\"trade.precreate\",\"requestTimestamp\":\"2018-09-17 17:02:33\",\"msgSrc\":\"WWW.TEST.COM\",\"sign\":\"e0ad8dd33deb6d93064b153e682232ce\",\"mid\":\"898310148160568\",\"notifyUrl\":\"http://testapi.yohops.com/payment/weixin_notify\",\"tid\":\"00000001\",\"merOrderId\":\"31949755628692241\",\"instMid\":\"APPDEFAULT\"}";
HttpClient httpClient = new HttpClient();
httpClient.init();
String result = httpClient.post(url, JSON.toJSONString(data));
... ... @@ -93,16 +106,17 @@ public class PayTest {
data.put("msgType", "uac.appOrder"); // 微信:wx.unifiedOrder, 支付宝:trade.precreate, 全民付:qmf.order, 银联云闪付:uac.appOrder
data.put("requestTimestamp", DateUtil.date2String(new Date(), "yyyy-MM-dd HH:mm:ss"));
// 支付宝- 31945075157
data.put("merOrderId", "3194"+"24253748567");
data.put("merOrderId", "3194"+"9755628692241");
data.put("mid", "898310148160568"); //商户号 仅用于支付宝和云闪付
data.put("tid","00000001"); //终端号
data.put("instMid", "APPDEFAULT"); // 机构商户号
data.put("totalAmount", 1);
data.put("tradeType","APP");
// data.put("tradeType","APP");
data.put("sign", getSign(data));
HttpClient httpClient = new HttpClient();
httpClient.init();
String result = httpClient.post(url, JSON.toJSONString(data));
... ...
package com.yohoufo.order.service.code;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.service.code.service.impl.OrderCodeGenerator;
import com.yohoufo.order.service.code.service.impl.OrderCodeGeneratorImpl;
public class CodeTest {
public static void main(String[] args){
// OrderCodeGenerator orderCodeGenerator = new OrderCodeGeneratorImpl();
//
// for (int i =0; i <100 ; i++){
// long result = orderCodeGenerator.genId();
// System.out.println(result);
// System.out.println("反解结果: "+ orderCodeGenerator.expId(result));
// System.out.println("========================");
// }
OrderCodeGenerator orderCodeGenerator = new OrderCodeGeneratorImpl();
for (int i =0; i <10 ; i++){
long result = orderCodeGenerator.generate(OrderCodeType.BUYER_TYPE);
System.out.println(result);
System.out.println("反解结果: "+ orderCodeGenerator.expId(result));
System.out.println("========================");
}
System.out.println(1<<3);
// System.out.println(1<<3);
}
}
... ...
package com.yohoufo.order.service.code.service.impl;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
/**
* 订单号生成
*/
public interface OrderCodeGenerator {
/**
* 生成订单号
* @param type
* @return
*/
long generate(OrderCodeType type);
/**
* 反解
* @param id
* @return
*/
CodeMeta expId(long id);
}
... ...
package com.yohoufo.order.service.code.service.impl;
import com.yohoufo.order.common.OrderCodeType;
import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta;
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
import com.yohoufo.order.service.support.codegenerator.converter.IdConverterHelper;
import com.yohoufo.order.service.support.codegenerator.populater.AtomicIdPopulator;
import com.yohoufo.order.service.support.codegenerator.timer.SimpleTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OrderCodeGeneratorImpl implements OrderCodeGenerator {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
CodeBitMeta idBitMeta = new CodeBitMeta();
SimpleTimer timer ;
AtomicIdPopulator idPopulator;
public OrderCodeGeneratorImpl() {
init();
}
/**
* 机器节点: 取值0-7
*/
private long machineId;
public void init() {
if (timer == null){
timer = new SimpleTimer();
}
if (idPopulator == null){
idPopulator = new AtomicIdPopulator();
}
machineId = 1;
// 3位 0~8
validateMachineId(this.machineId);
}
public long generate(OrderCodeType type) {
CodeMeta id = new CodeMeta();
id.setMachine(machineId);
id.setType(type.getType());
idPopulator.populateId(timer, id, idBitMeta);
System.out.println(id.getTime());
// long time = id.getTime() & idBitMeta.getTimeBitsMask();
// id.setTime(time);
long ret = IdConverterHelper.convert(id, this.idBitMeta);
return ret;
}
public CodeMeta expId(long id) {
return IdConverterHelper.convert(id, this.idBitMeta);
}
private void validateMachineId(long machineId){
if (machineId < 0) {
log.error("The machine ID is not configured properly (" + machineId + " < 0) so that Vesta Service refuses to start.");
throw new IllegalStateException(
"The machine ID is not configured properly (" + machineId + " < 0) so that Vesta Service refuses to start.");
} else if (machineId >= (1 << this.idBitMeta.getMachineBits())) {
log.error("The machine ID is not configured properly ("
+ machineId + " >= " + (1 << this.idBitMeta.getMachineBits()) + ") so that Vesta Service refuses to start.");
throw new IllegalStateException("The machine ID is not configured properly ("
+ machineId + " >= " + (1 << this.idBitMeta.getMachineBits()) + ") so that Vesta Service refuses to start.");
}
}
}
\ No newline at end of file
... ...
... ... @@ -124,6 +124,11 @@ public class ProductController {
return new ApiResponse(200, "卖出成功!", Boolean.TRUE);
}
/**
*
* @param skup
* @return
*/
@IgnoreSignature
@IgnoreSession
@RequestMapping(params = "method=ufo.product.cancelSaleSkup")
... ...
... ... @@ -65,3 +65,11 @@ sdk.instanceName=yohopic
yoho.recovery.zkPath=/yh/config/recovery
env.machineId=0
unionpay.pay.callbackUrl=http://testapi.yohops.com/payment/weixin_notify
unionpay.pay.url=https://qr-test2.chinaums.com/netpay-route-server/api/
unionpay.pay.msgSrc=WWW.TEST.COM
unionpay.pay.mid=898310148160568
unionpay.pay.tid=00000001
unionPay.pay.signKey=fcAmtnx7MwismjWNhNKdHC44mNXtnEQeJkRrhKJwyrW2ysRR
... ...
... ... @@ -6,6 +6,21 @@ datasources:
username: yh_test
password: 9nm0icOwt6bMHjMusIfMLw==
ufo_order:
servers:
- 192.168.102.219:3306
- 192.168.102.219:3306
username: yh_test
password: 9nm0icOwt6bMHjMusIfMLw==
daos:
- com.yohoufo.dal.order.BuyerOrderGoodsMapper
- com.yohoufo.dal.order.BuyerOrderMapper
- com.yohoufo.dal.order.BuyerOrderMetaMapper
- com.yohoufo.dal.order.ExpressInfoMapper
- com.yohoufo.dal.order.SellerOrderGoodsMapper
- com.yohoufo.dal.order.SellerOrderMapper
- com.yohoufo.dal.order.SellerOrderMetaMapper
yh_passport:
servers:
- 192.168.102.219:3306
... ...
... ... @@ -43,3 +43,6 @@ sdk.instanceId=${sdk.instanceId}
sdk.instanceName=${sdk.instanceName}
yoho.single.center.domain=${yoho.single.center.domain}
unionpay.pay.url=${unionpay.pay.url}
... ...