@PostMapping("qrCode")
@ApiOperation(value = "扫码支付", notes = "userId 用户id,vipId ")
public ResultBody qrCode(HttpServletRequest request, Integer userId, Integer vipId) {
ResultBody body = new ResultBody(ResultBody.SUCCESS, "SUCCESS");
try {
String ip = HttpUtils.getClientIp(request);
PayInfoModel model = paymentService.buyVip(userId, vipId, ip);
String cc= generateQRCodeImages(model.getCodeUrl(), 350, 350);
cc = cc.replaceAll("[\\t\\n\\r]","");
body.setResult("data:image/png;base64,"+cc);//生成base64给前端,body自己定义返回的工具类
} catch (SysException e) {
body = new ResultBody(ResultBody.FAILED, e.getMessage());
} catch (IOException e) {
e.printStackTrace();
} catch (WriterException e) {
e.printStackTrace();
}
return body;
}
private static String generateQRCodeImages(String text, int width, int height) throws WriterException, IOException {
String binary = null;
QRCodeWriter qrCodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, width, height);
ByteArrayOutputStream out = new ByteArrayOutputStream();
MatrixToImageWriter.writeToStream(bitMatrix,"PNG",out);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(out.toByteArray());
byte[] bytes = new byte[out.size()];
byteArrayInputStream.read(bytes);
BASE64Encoder encoder = new BASE64Encoder();
String base64 = encoder.encode(bytes);
return base64;
}
获取ip的工具类
package com.dagen.imgs.support.utils;
import javax.servlet.http.HttpServletRequest;
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.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
/**
* Http Post Get 工具
*/
public class HttpUtils {
public static String doPost(String url, String data) throws Exception {
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpPost httpPost = new HttpPost(url);
if (!StringUtils.isEmpty(data)) {
StringEntity entity = new StringEntity(data);
httpPost.setEntity(entity);
}
CloseableHttpResponse response = httpClient.execute(httpPost);
return EntityUtils.toString(response.getEntity());
}
public static String doGet(String url) throws Exception {
CloseableHttpClient httpClient = HttpClients.custom().build();
HttpGet httpGet = new HttpGet(url);
CloseableHttpResponse response = httpClient.execute(httpGet);
return EntityUtils.toString(response.getEntity());
}
public static String getClientIp(HttpServletRequest request) {
if (request == null) {
return "127.0.0.1";
}
String ip = request.getHeader("X-Requested-For");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
service层按照自己的需求写逻辑代码
@Override
public PayInfoModel buyVip(Integer userId,Integer vipId, String ip) throws SysException {
if (userId == null) {
throw new SeException("User id 不能为空");
}
if (StringUtils.isEmpty(ip)) {
throw new SeException("ip 不能为空");
}
if (vipId==null) {
throw new SeException("vipId 不能为空");
}
UserPo user = userService.findById(userId);
if (user == null) {
throw new SeException("用户不存在");
}
VipPo vipPo=userService.findVip(vipId);
if (vipPo == null) {
throw new SeException("vip类型不存在");
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
int ran = (int)((Math.random() * 9 + 1) * 100000);
String tradeNo = simpleDateFormat.format(new Date()) + ran;
String totalFee =vipPo.getMoney();
//String tradeNo = "NS" + System.currentTimeMillis();
OrdersPO orders = new OrdersPO();
orders.setUserId(userId);
orders.setTitle("开通会员");
orders.setDay(vipPo.getTimeDay());
orders.setMoney(Double.parseDouble(totalFee));
orders.setState("2");//订单状态1支付2未支付
orders.setPhone(user.getPhone());
orders.setNick(user.getNick());
orders.setOrderNumber(tradeNo);
orders.setType("2");//类型1支付宝2微信
paymentDao.save(orders);
PayInfoModel model = payService.build(tradeNo, totalFee + "00", ip);
return model;
}
调微信支付
package com.dagen.imgs.support.payment;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import com.dagen.imgs.config.se.SysException;
import com.dagen.imgs.support.payment.wechat.WXPayUtil;
import com.dagen.imgs.support.payment.wechat.WXPayConstants.SignType;
import com.dagen.imgs.support.utils.HttpUtils;
import lombok.extern.log4j.Log4j2;
@Log4j2
public class PayService {
private final static String WECHAT_PAY_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
private String appId;
private String mchId;
private String apiKey;
private String notifyUrl;
public PayService(String appId, String mchId, String key, String notifyUrl) {
this.appId = appId;
this.mchId = mchId;
this.apiKey = key;
this.notifyUrl = notifyUrl;
}
private String getOrderExpireTime(Long expire) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date now = new Date();
Date afterDate = new Date(now.getTime() + expire);
return sdf.format(afterDate);
}
public PayInfoModel build(String tradeNo, String totalFee, String ip) throws SysException {
PayInfoModel model = new PayInfoModel();
SortedMap<String, String> data = new TreeMap<String, String>();
try {
data.put("appid", this.appId);
data.put("mch_id", this.mchId);
data.put("nonce_str", WXPayUtil.generateNonceStr());
data.put("body", "开通VIP");
data.put("out_trade_no", tradeNo);
data.put("total_fee", totalFee);
data.put("spbill_create_ip", ip);
data.put("notify_url", this.notifyUrl);
data.put("trade_type", "NATIVE");
String timeExpire = this.getOrderExpireTime(2 * 60 * 1000L);
data.put("time_expire", timeExpire);
String generateSignature = WXPayUtil.generateSignature(data, apiKey, SignType.MD5);
data.put("sign", generateSignature);
String generateSignedXml = WXPayUtil.generateSignedXml(data, apiKey);
String postData = new String(generateSignedXml.getBytes("UTF-8"), "ISO-8859-1");
log.info("WeChat pay build xml -> \r\n" + generateSignedXml);
String result = HttpUtils.doPost(WECHAT_PAY_URL, postData);
log.info("WeChat pay result xml -> \r\n" + result);
Map<String,String> map = WXPayUtil.xmlToMap(result);
if("SUCCESS".equalsIgnoreCase(map.get("return_code"))) {
model.setCodeUrl(map.get("code_url"));
}
model.setReturnCode(map.get("return_code"));
model.setReturnMsg(map.get("return_msg"));
} catch (Exception e) {
throw new SysException(e);
}
return model;
}
}
微信回调
@Override
public void notify(String request) throws SysException {
try {
Map<String, String> map = WXPayUtil.xmlToMap(request);
if ("SUCCESS".equalsIgnoreCase(map.get("result_code"))) {
String tradeNo = map.get("out_trade_no");
OrdersPO order = paymentDao.findByOrderNumber(tradeNo);
if("1".equals(order.getState())) {
return;
}
//按照自己的业务写
}
} catch (Exception e) {
throw new SysException(e);
}
}