
微信提供
HttpClient.java 工具类
package cn.itcast.core.util;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
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.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
/**
* http请求客户端
*
* @author Administrator
*
*/
public class HttpClient {
private String url;
private Map<String, String> param;
private int statusCode;
private String content;
private String xmlParam;
private boolean isHttps;
public boolean isHttps() {
return isHttps;
}
public void setHttps(boolean isHttps) {
this.isHttps = isHttps;
}
public String getXmlParam() {
return xmlParam;
}
public void setXmlParam(String xmlParam) {
this.xmlParam = xmlParam;
}
public HttpClient(String url, Map<String, String> param) {
this.url = url;
this.param = param;
}
public HttpClient(String url) {
this.url = url;
}
public void setParameter(Map<String, String> map) {
param = map;
}
public void addParameter(String key, String value) {
if (param == null)
param = new HashMap<String, String>();
param.put(key, value);
}
public void post() throws ClientProtocolException, IOException {
HttpPost http = new HttpPost(url);
setEntity(http);
execute(http);
}
public void put() throws ClientProtocolException, IOException {
HttpPut http = new HttpPut(url);
setEntity(http);
execute(http);
}
public void get() throws ClientProtocolException, IOException {
if (param != null) {
StringBuilder url = new StringBuilder(this.url);
boolean isFirst = true;
for (String key : param.keySet()) {
if (isFirst)
url.append("?");
else
url.append("&");
url.append(key).append("=").append(param.get(key));
}
this.url = url.toString();
}
HttpGet http = new HttpGet(url);
execute(http);
}
/**
* set http post,put param
*/
private void setEntity(HttpEntityEnclosingRequestBase http) {
if (param != null) {
List<NameValuePair> nvps = new LinkedList<NameValuePair>();
for (String key : param.keySet())
nvps.add(new BasicNameValuePair(key, param.get(key))); // 参数
http.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8)); // 设置参数
}
if (xmlParam != null) {
http.setEntity(new StringEntity(xmlParam, Consts.UTF_8));
}
}
private void execute(HttpUriRequest http) throws ClientProtocolException,
IOException {
CloseableHttpClient httpClient = null;
try {
if (isHttps) {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(null, new TrustStrategy() {
// 信任所有
public boolean isTrusted(X509Certificate[] chain,
String authType)
throws CertificateException {
return true;
}
}).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslContext);
httpClient = HttpClients.custom().setSSLSocketFactory(sslsf)
.build();
} else {
httpClient = HttpClients.createDefault();
}
CloseableHttpResponse response = httpClient.execute(http);
try {
if (response != null) {
if (response.getStatusLine() != null)
statusCode = response.getStatusLine().getStatusCode();
HttpEntity entity = response.getEntity();
// 响应内容
content = EntityUtils.toString(entity, Consts.UTF_8);
}
} finally {
response.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpClient.close();
}
}
public int getStatusCode() {
return statusCode;
}
public String getContent() throws ParseException, IOException {
return content;
}
}
BuyerCartServiceImpl
package cn.itcast.core.service;
import cn.itcast.core.dao.item.ItemDao;
import cn.itcast.core.pojo.entity.BuyerCart;
import cn.itcast.core.pojo.item.Item;
import cn.itcast.core.pojo.order.OrderItem;
import cn.itcast.core.util.Constants;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Service
public class BuyerCartServiceImpl implements BuyerCartService {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ItemDao itemDao;
@Override
public List<BuyerCart> addItemToCartList(List<BuyerCart> cartList, Long itemId, Integer num) {
//1. 根据商品SKU ID查询SKU商品信息
Item item = itemDao.selectByPrimaryKey(itemId);
//2. 判断商品是否存在不存在, 抛异常
if (item == null) {
throw new RuntimeException("您购买的商品不存在!");
}
//3. 判断商品状态是否为1已审核, 状态不对抛异常
if (!"1".equals(item.getStatus())) {
throw new RuntimeException("您购买的商品非法!");
}
//4.获取商家ID
String sellerId = item.getSellerId();
//5.根据商家ID查询购物车列表中是否存在该商家的购物车
BuyerCart buyerCart = findCartBySellerId(sellerId, cartList);
//6.判断如果购物车列表中不存在该商家的购物车
if (buyerCart == null) {
//6.a.1 新建购物车对象
buyerCart = new BuyerCart();
//向购物车中加入卖家id
buyerCart.setSellerId(sellerId);
//向购物车中加入卖家名称
buyerCart.setSellerName(item.getSeller());
//创建购物车中需要的购物项集合
List<OrderItem> orderItemList = new ArrayList<>();
//创建购物项对象
OrderItem orderItem = createOrderItem(item, num);
//购物项加入购物项集合中
orderItemList.add(orderItem);
//向购物车中加入购物项集合
buyerCart.setOrderItemList(orderItemList);
//6.a.2 将新建的购物车对象添加到购物车列表
cartList.add(buyerCart);
} else {
//6.b.1如果购物车列表中存在该商家的购物车 (查询购物车明细列表中是否存在该商品)
List<OrderItem> orderItemList = buyerCart.getOrderItemList();
OrderItem orderItem = findOrderItemByItemId(orderItemList, itemId);
//6.b.2判断购物车明细是否为空
if (orderItem == null) {
//6.b.3为空,新增购物车明细
orderItem = createOrderItem(item, num);
//将新建的购物项对象放入购物项集合中
orderItemList.add(orderItem);
} else {
//6.b.4不为空,在原购物车明细上添加数量,更改金额
orderItem.setNum(orderItem.getNum() + num);
orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(orderItem.getNum())));
}
//6.b.5如果购物车明细中数量操作后小于等于0,则移除
if (orderItem.getNum() <= 0) {
orderItemList.remove(orderItem);
}
//6.b.6如果购物车中购物车明细列表为空,则移除
if (orderItemList.size() == 0) {
cartList.remove(buyerCart);
}
}
//7. 返回购物车列表对象
return cartList;
}
/**
* 从购物项集合中找符合itemId的同款购物项
* @param orderItemList 购物项集合
* @param itemId 库存id
* @return
*/
private OrderItem findOrderItemByItemId(List<OrderItem> orderItemList, Long itemId) {
if (orderItemList != null) {
for (OrderItem orderItem : orderItemList) {
if (itemId.equals(orderItem.getItemId())) {
return orderItem;
}
}
}
return null;
}
/**
* 创建购物项对象
* @param item 库存对象
* @param num 购买商品数量
* @return
*/
private OrderItem createOrderItem(Item item, Integer num) {
if (num == null || num <= 0) {
throw new RuntimeException("您购买数量非法!");
}
OrderItem orderItem = new OrderItem();
//库存标题
orderItem.setTitle(item.getTitle());
//购买数量
orderItem.setNum(num);
//卖家id
orderItem.setSellerId(item.getSellerId());
//商品单价
orderItem.setPrice(item.getPrice());
//示例图片地址
orderItem.setPicPath(item.getImage());
//库存id
orderItem.setItemId(item.getId());
//商品id
orderItem.setGoodsId(item.getGoodsId());
//总价 = 单价 * 购买数量
orderItem.setTotalFee(orderItem.getPrice().multiply(new BigDecimal(num)));
return orderItem;
}
/**
* 从购物车列表中获取这个卖家的购物车
* @param sellerId 卖家id
* @param cartList 购物车列表
* @return
*/
private BuyerCart findCartBySellerId(String sellerId, List<BuyerCart> cartList) {
if (cartList != null) {
for (BuyerCart cart : cartList) {
if (sellerId.equals(cart.getSellerId())) {
return cart;
}
}
}
return null;
}
@Override
public void setCartListToRedis(String userName, List<BuyerCart> cartList) {
redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).put(userName, cartList);
}
@Override
public List<BuyerCart> getCartListFromRedis(String userName) {
List<BuyerCart> cartList = (List<BuyerCart>)redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).get(userName);
if (cartList == null) {
cartList = new ArrayList<BuyerCart>();
}
return cartList;
}
@Override
public List<BuyerCart> mergeCookieCartListToRedisCartList(List<BuyerCart> cookieCartList, List<BuyerCart> redisCartList) {
if (cookieCartList != null) {
//遍历cookie购物车集合
for (BuyerCart cart : cookieCartList) {
List<OrderItem> orderItemList = cart.getOrderItemList();
if (orderItemList != null) {
//遍历cookie中的购物项集合
for (OrderItem orderItem : orderItemList) {
//向redis购物车集合中加入cookie中的购物项
redisCartList = addItemToCartList(redisCartList, orderItem.getItemId(), orderItem.getNum());
}
}
}
}
return redisCartList;
}
}
OrderServiceImpl
package cn.itcast.core.service;
import cn.itcast.core.dao.log.PayLogDao;
import cn.itcast.core.dao.order.OrderDao;
import cn.itcast.core.dao.order.OrderItemDao;
import cn.itcast.core.pojo.entity.BuyerCart;
import cn.itcast.core.pojo.log.PayLog;
import cn.itcast.core.pojo.order.Order;
import cn.itcast.core.pojo.order.OrderItem;
import cn.itcast.core.util.Constants;
import cn.itcast.core.util.IdWorker;
import com.alibaba.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
@Autowired
private IdWorker idWorker;
@Autowired
private PayLogDao payLogDao;
@Autowired
private OrderDao orderDao;
@Autowired
private OrderItemDao orderItemDao;
@Autowired
private RedisTemplate redisTemplate;
@Override
public void add(Order order, List<BuyerCart> cartList) {
/**
* 1. 遍历购物车集合
* 每一个购物车对象, 都保存一条order订单表数据
*/
List<String> orderIdList=new ArrayList();//订单ID列表
double total_money=0;//总金额 (元)
for(BuyerCart cart:cartList){
//生成一个id
long orderId = idWorker.nextId();
System.out.println("sellerId:"+cart.getSellerId());
Order tborder=new Order();//新创建订单对象
tborder.setOrderId(orderId);//订单ID
tborder.setUserId(order.getUserId());//用户名
tborder.setPaymentType(order.getPaymentType());//支付类型
tborder.setStatus("1");//状态:未付款
tborder.setCreateTime(new Date());//订单创建日期
tborder.setUpdateTime(new Date());//订单更新日期
tborder.setReceiverAreaName(order.getReceiverAreaName());//地址
tborder.setReceiverMobile(order.getReceiverMobile());//手机号
tborder.setReceiver(order.getReceiver());//收货人
tborder.setSourceType(order.getSourceType());//订单来源
tborder.setSellerId(cart.getSellerId());//商家ID
/**
* 2. 遍历购物项集合
* 每一个购物项对象, 都保存一条order_item订单详情表数据
*/
double money=0;
for(OrderItem orderItem :cart.getOrderItemList()){
orderItem.setId(idWorker.nextId());
orderItem.setOrderId( orderId );//订单ID
orderItem.setSellerId(cart.getSellerId());
money+=orderItem.getTotalFee().doubleValue();//金额累加
orderItemDao.insertSelective(orderItem);
}
tborder.setPayment(new BigDecimal(money));
orderDao.insertSelective(tborder);
orderIdList.add(orderId+"");//添加到订单列表
total_money+=money;//累加到总金额
}
/**
* 3. 根据遍历过程中计算的总价钱, 保存一条支付日志数据
*/
if("1".equals(order.getPaymentType())){//如果是微信支付
PayLog payLog=new PayLog();
String outTradeNo= idWorker.nextId()+"";//支付订单号
payLog.setOutTradeNo(outTradeNo);//支付订单号
payLog.setCreateTime(new Date());//创建时间
//订单号列表,逗号分隔
String ids=orderIdList.toString().replace("[", "").replace("]", "").replace(" ", "");
payLog.setOrderList(ids);//订单号列表,逗号分隔
payLog.setPayType("1");//支付类型
payLog.setTotalFee( (long)(total_money*100 ) );//总金额(分)
payLog.setTradeState("0");//支付状态
payLog.setUserId(order.getUserId());//用户ID
payLogDao.insert(payLog);//插入到支付日志表
//将支付日志(未支付状态), 保存到redis中, 供支付使用
redisTemplate.boundHashOps(Constants.REDIS_PAYLOG).put(order.getUserId(), payLog);//放入缓存
}
/**
* 4. 保存支付日志, 订单集合, 订单详情集合完成后, 清空redis中的购物车
*/
redisTemplate.boundHashOps(Constants.REDIS_CARTLIST).delete(order.getUserId());
}
@Override
public PayLog findPayLogFromRedis(String userName) {
PayLog payLog = (PayLog)redisTemplate.boundHashOps(Constants.REDIS_PAYLOG).get(userName);
if (payLog == null) {
payLog = new PayLog();
}
return payLog;
}
@Override
public void updateOrderStatus(String out_trade_no, String transaction_id) {
/**
* 1.修改支付日志支付状态
*/
PayLog payLog = payLogDao.selectByPrimaryKey(out_trade_no);
//支付时间
payLog.setPayTime(new Date());
//支付状态改为1, 已支付
payLog.setTradeState("1");
//交易号, 微信给我们返回的
payLog.setTransactionId(transaction_id);
//更新支付日志到数据库中
payLogDao.updateByPrimaryKeySelective(payLog);
/**
* 2.修改订单支付状态
*/
String orderList = payLog.getOrderList();//获取订单号列表
String[] orderIds = orderList.split(",");//获取订单号数组
if (orderIds != null) {
for (String orderId : orderIds) {
Order order = new Order();
order.setStatus("2");//已付款
order.setOrderId(Long.parseLong(orderId));
orderDao.updateByPrimaryKeySelective(order);
}
}
/**
* 3. 清除redis缓存中的未支付日志数据
*/
redisTemplate.boundHashOps(Constants.REDIS_PAYLOG).delete(payLog.getUserId());
}
}
PayServiceImpl
package cn.itcast.core.service;
import cn.itcast.core.util.HttpClient;
import com.alibaba.dubbo.config.annotation.Service;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.beans.factory.annotation.Value;
import java.util.HashMap;
import java.util.Map;
@Service
public class PayServiceImpl implements PayService {
//微信公众账号或开放平台APP的唯一标识
@Value("${appid}")
private String appid;
//财付通平台的商户账号
@Value("${partner}")
private String partner;
//财付通平台的商户密钥
@Value("${partnerkey}")
private String partnerkey;
/**
* 调用微信下单接口生成支付链接
*
* @param tradeNo 支付单号
* @param totalFee 订单金额
* @return
*/
@Override
public Map createNative(String tradeNo, String totalFee) {
//1.创建参数
Map<String, String> param = new HashMap();//创建参数
param.put("appid", appid);//公众号
param.put("mch_id", partner);//商户号
param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
param.put("body", "品优购");//商品描述
param.put("out_trade_no", tradeNo);//商户订单号
param.put("total_fee", totalFee);//总金额(分)
param.put("spbill_create_ip", "127.0.0.1");//IP
param.put("notify_url", "http://www.itcast.cn");//回调地址(随便写)
param.put("trade_type", "NATIVE");//交易类型
try {
//2.生成要发送的xml格式数据
String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
System.out.println(xmlParam);
//调用微信统一下单接口, 通过httpClient工具发送请求
HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
//使用https协议发送
client.setHttps(true);
//发送的xml格式字符串数据
client.setXmlParam(xmlParam);
//使用post请求发送
client.post();
//3.发送请求并获得结果
String result = client.getContent();
System.out.println(result);
//调用微信工具类, 将返回的xml格式字符串转换成map格式
Map<String, String> resultMap = WXPayUtil.xmlToMap(result);
Map<String, String> map = new HashMap<>();
map.put("code_url", resultMap.get("code_url"));//支付链接
map.put("total_fee", totalFee);//总金额
map.put("out_trade_no", tradeNo);//订单号
return map;
} catch (Exception e) {
e.printStackTrace();
return new HashMap<>();
}
}
@Override
public Map queryPayStatus(String tradeNo) {
//封装发送的数据参数
Map param = new HashMap();
param.put("appid", appid);//公众账号ID
param.put("mch_id", partner);//商户号
param.put("out_trade_no", tradeNo);//订单号
param.put("nonce_str", WXPayUtil.generateNonceStr());//随机字符串
//发送的地址
String url = "https://api.mch.weixin.qq.com/pay/orderquery";
try {
//调用微信工具类, 将封装的发送参数, 转换成xml格式字符串
String xmlParam = WXPayUtil.generateSignedXml(param, partnerkey);
//使用httpClient工具发送https请求, 到微信服务器
HttpClient client = new HttpClient(url);
//设置使用https协议
client.setHttps(true);
//设置发送的内容
client.setXmlParam(xmlParam);
//设置post请求发送
client.post();
//发送并返回结果, 结果为xml格式字符串
String result = client.getContent();
//调用微信工具类, 将返回的xml格式字符串转换成Map
Map<String, String> map = WXPayUtil.xmlToMap(result);
System.out.println(map);
return map;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
PayController
package cn.itcast.core.controller;
import cn.itcast.core.pojo.entity.Result;
import cn.itcast.core.pojo.log.PayLog;
import cn.itcast.core.service.OrderService;
import cn.itcast.core.service.PayService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* 支付流程
*/
@RestController
@RequestMapping("/pay")
public class PayController {
@Reference
private OrderService orderService;
@Reference
private PayService payService;
/**
* 生成支付链接
*/
@RequestMapping("/createNative")
public Map createNative() {
//1.获取当前登录用户的用户名
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
//2.根据当前登录的用户的用户名到redis中获取未支付的日志记录
PayLog payLog = orderService.findPayLogFromRedis(userName);
//3.根据日志对象中的支付单号和总金额调用,微信同意下单接口,生成支付链接返回
//"1"String.valueof(paylog.getTotalFee())
Map resultMap = payService.createNative(payLog.getOutTradeNo(), "1");
return resultMap;
}
@RequestMapping("/queryPayStatus")
public Result queryPayStatus(String out_trade_no) {
Result result = null;
int flag = 1;
//1.死循环
while (true) {
//2.根据支付单号.调用微信的查询订单就扣查询支付状态
Map resultMap = payService.queryPayStatus(out_trade_no);
//3.如果返回空的对象表示支付超时
if (resultMap == null) {
result = new Result(false, "二维码超时");
break;
}
//4.如果返回数据中trade_state属性为SUCCESS代表支付成功
if ("SUCCESS".equals(resultMap.get("trade_state"))) {
orderService.updateOrderStatus(out_trade_no, String.valueOf(resultMap.get("transaction_id")));
result = new Result(true, "支付成功");
break;
}
//超过20分钟未支付,这支付超时
if (flag >= 400) {
result = new Result(false, "二维码超时");
break;
}
}
try {
Thread.sleep(3000);
flag++;
} catch (InterruptedException e) {
e.printStackTrace();
result = new Result(false, "二维码超时");
}
return result;
}
}
OrderController
package cn.itcast.core.controller;
import cn.itcast.core.pojo.entity.BuyerCart;
import cn.itcast.core.pojo.entity.Result;
import cn.itcast.core.pojo.order.Order;
import cn.itcast.core.service.BuyerCartService;
import cn.itcast.core.service.OrderService;
import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
@Reference
private OrderService orderService;
@Reference
private BuyerCartService buyerCartService;
/**
* 提交订单
* @param order 页面传入这个对象里面只有收货人地址, 联系人姓名, 手机号
* @return
*/
@RequestMapping("/add")
public Result add(@RequestBody Order order) {
try {
//1. 获取当前登录用户的用户名
String userName = SecurityContextHolder.getContext().getAuthentication().getName();
//2. 将当前用户的用户名放入页面传进来的order对象中
order.setUserId(userName);
//3. 通过登录用户的用户名获取这个人的购物车列表
List<BuyerCart> cartList = buyerCartService.getCartListFromRedis(userName);
//3. 保存订单
orderService.add(order, cartList);
return new Result(true, "保存订单成功!");
} catch (Exception e) {
e.printStackTrace();
return new Result(false, "保存订单失败!");
}
}
}
来源:https://www.cnblogs.com/lei0913/p/10890537.html