原作者 https://blog.csdn.net/weixin_44142296/article/details/87078045
使用 com.github.binarywang 包
pom.xml支持
com.github.binarywang
weixin-java-mp
3.3.0
com.github.binarywang
weixin-java-pay
3.3.0
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Api("微信支付")
@Controller
@RequestMapping("/API/V1")
public class WXMpController {
@Autowired
WxMpService wxMpService;
@Autowired
WxPayService wxPayService;
private static Logger log = LoggerFactory.getLogger(WXMpController.class);
/**
*
String baseUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=微信那边给的appId&" +
"redirect_uri=自己这面需要获得授权的页面地址&" +
"response_type=code&scope=snsapi_userinfo&state=chuai#wechat_redirect";
* 1、引导用户进入授权页面同意授权,获取code
* @return
*/
@ResponseBody
@RequestMapping("/wechat/authorize")
public String getWxMpCode(String returnUrl){
if(returnUrl!=null) {
returnUrl = URLEncoder.encode(returnUrl);
}
String baseUrl = wxMpService.oauth2buildAuthorizationUrl(
"http://shanhuo.natappvip.cc/sell/wechat",
WxConsts.OAuth2Scope.SNSAPI_USERINFO,
returnUrl);
logger.info("baseUrl打印:{}",baseUrl);
return "redirect:"+baseUrl;
}
/**
* 获取用户信息 openid 、accessToken等
*
* @param code
* @param state
* @return
*/
@ResponseBody
@RequestMapping("/wechat")
public BaseResult getUser(String code, String state) {
BaseResult baseResult = new BaseResult();
WxMpOAuth2AccessToken accessToken = new WxMpOAuth2AccessToken();
try {
accessToken = wxMpService.oauth2getAccessToken(code);
} catch (WxErrorException e) {
e.printStackTrace();
}
String openId = accessToken.getOpenId();
accessToken.getAccessToken();
baseResult.setCode(200);
baseResult.setData(openId);
return baseResult;
}
/**
* 唤醒支付
*
* @param orderId
* @param openid
* @return
*/
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@ResponseBody
@RequestMapping("/pay/create")
public BaseResult parCreate(Model m, int orderId, String openid, String key, HttpServletRequest request) {
log.info("进入pay/create方法。。。{}", wxPayService);
//获取用户ID 写的很垃圾 原谅下我
String ip = null;
ip = request.getHeader("X-Forwarded-For");
if (null == ip) {
ip = request.getRemoteAddr();
}
WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest();
orderRequest.setAttach("携带的参数给回调接口 此处我写的是用户的ID 根据自己的业务");
orderRequest.setOpenid(openid);
orderRequest.setBody("center");
//自己生成订单号 随机字符串
orderRequest.setOutTradeNo((PassWord.getRandom(24, PassWord.TYPE.LETTER)));
orderRequest.setTotalFee(BaseWxPayRequest.yuanToFen(0.001));//元转成分
orderRequest.setSpbillCreateIp(ip);
orderRequest.setNotifyUrl("shejiaobang.xyz/notify/order"); //回调地址
orderRequest.setTradeType("JSAPI"); //支付类型
try {
WxPayMpOrderResult wxPayMpOrderResult = wxPayService.createOrder(orderRequest);
BaseResult baseResult = new BaseResult();
baseResult.setData(wxPayMpOrderResult);
baseResult.setCode(200);
return baseResult;
} catch (WxPayException e) {
log.info("微信支付失败!订单号:{},原因:{}", orderId, e.getMessage());
e.printStackTrace();
return BaseResult.invalidRequest();
}
}
@RequestMapping("notify/order")
public void PayResultNotify(HttpServletRequest request, HttpServletResponse response) throws IOException {
log.info("微信支付返回通知函数开始---------------------");
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray(), "utf-8");
boolean isPayOk = false;
WxPayOrderNotifyResult wxPayOrderNotifyResult = null;
// 此处调用订单查询接口验证是否交易成功
try {
wxPayOrderNotifyResult = wxPayService.parseOrderNotifyResult(result);
if ("SUCCESS".equals(wxPayOrderNotifyResult.getResultCode())) {
isPayOk = true;
}
log.info("解析数据:" + wxPayOrderNotifyResult.toString());
} catch (WxPayException e) {
e.printStackTrace();
}
String noticeStr = "";
// 支付成功,商户处理后同步返回给微信参数
PrintWriter writer = response.getWriter();
if (isPayOk) {
//此处写自己的业务
// 通知微信已经收到消息,不要再给我发消息了,否则微信会8连击调用本接口
noticeStr = setXML("SUCCESS", "OK");
writer.write(noticeStr);
writer.flush();
} else {
// 支付失败, 记录流水失败
noticeStr = setXML("FAIL", "");
writer.write(noticeStr);
writer.flush();
System.out.println("===============支付失败==============");
}
}
/**
* 通知微信接收回调成功
*
* @return_code SUCCESS
* @return_msg OK
* @return
*/
public static String setXML(String return_code, String return_msg) {
return " ";
}
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 微信参数工具类
*/
@Configuration
//此处有可能会亮红色下划线 属于 idea 警告 可以忽视
@ConfigurationProperties(prefix = "wechat")
public class WxConfig {
private String appid;
private String appSecret;
private String mchId;
private String mchKey;
private String keyPath;
@Bean
public WxMpInMemoryConfigStorage initStorage(){
WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
config.setAppId(appid);
config.setSecret(appSecret);
return config;
}
@Bean
public WxMpService initWxMpService(){
WxMpService wxMpService= new WxMpServiceImpl();
wxMpService.setWxMpConfigStorage(initStorage());
return wxMpService;
}
@Bean
public WxPayService initWxPayService(){
WxPayService wxPayService= new WxPayServiceImpl();
WxPayConfig payConfig = new WxPayConfig();
payConfig.setAppId(appid);
payConfig.setMchId(mchId);
payConfig.setSignType(WxPayConstants.SignType.MD5);
payConfig.setMchKey(mchKey);
// payConfig.setKeyPath(keyPath); 此处是回调地址 上面写死了这个参数没用到我注释了
wxPayService.setConfig(payConfig);
return wxPayService;
}
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getMchKey() {
return mchKey;
}
public void setMchKey(String mchKey) {
this.mchKey = mchKey;
}
public String getKeyPath() {
return keyPath;
}
public void setKeyPath(String keyPath) {
this.keyPath = keyPath;
}
}
yml 格式
wechat:
appid: ********公众平台给的
appSecret: 公众平台给的 *******
mchId: ******公众平台给的
mchKey: 商户平台给的
下面是我的订单号随机生成类
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
/**
* 字符随机生成类
* @author ASUS
*
*/
public class PassWord {
/**
* 密码类型枚举
* @author ASUS
*/
public static enum TYPE {
/**
* 字符型
*/
LETTER,
/**
* 大写字符型
*/
CAPITAL,
/**
* 数字型
*/
NUMBER,
/**
* 符号型
*/
SIGN,
/**
* 大+小字符 型
*/
LETTER_CAPITAL,
/**
* 小字符+数字 型
*/
LETTER_NUMBER,
/**
* 大+小字符+数字 型
*/
LETTER_CAPITAL_NUMBER,
/**
* 大+小字符+数字+符号 型
*/
LETTER_CAPITAL_NUMBER_SIGN
}
private static String[] lowercase = {
"a","b","c","d","e","f","g","h","i","j","k",
"l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"};
private static String[] capital = {
"A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
private static String[] number = {
"1","2","3","4","5","6","7","8","9","0"};
private static String[] sign = {
"~","!","@","#","$","%","^","&","*","(",")","_","+","`","-","=",
"{","}","|",":","\"","<",">","?",
"[","]","\\",";","'",",",".","/"};
/**
* 静态随机数
*/
private static Random random = new Random();
/* public static void main(String[] args) {
System.out.println(PassWord.getRandom(24, PassWord.TYPE.LETTER));
}*/
/**
* 获取随机组合码
* @param num 位数
* @param type 类型
* @type
*
字符型 LETTER,
*
大写字符型 CAPITAL,
*
数字型 NUMBER,
*
符号型 SIGN,
*
大+小字符型 LETTER_CAPITAL,
*
小字符+数字 型 LETTER_NUMBER,
*
大+小字符+数字 型 LETTER_CAPITAL_NUMBER,
*
大+小字符+数字+符号 型 LETTER_CAPITAL_NUMBER_SIGN
*/
public static String getRandom(int num,TYPE type){
ArrayList temp = new ArrayList();
StringBuffer code = new StringBuffer();
if(type == TYPE.LETTER){
temp.addAll(Arrays.asList(lowercase));
}else if(type == TYPE.CAPITAL){
temp.addAll(Arrays.asList(capital));
}else if(type == TYPE.NUMBER){
temp.addAll(Arrays.asList(number));
}else if(type == TYPE.SIGN){
temp.addAll(Arrays.asList(sign));
}else if(type == TYPE.LETTER_CAPITAL){
temp.addAll(Arrays.asList(lowercase));
temp.addAll(Arrays.asList(capital));
}else if(type == TYPE.LETTER_NUMBER){
temp.addAll(Arrays.asList(lowercase));
temp.addAll(Arrays.asList(number));
}else if(type == TYPE.LETTER_CAPITAL_NUMBER){
temp.addAll(Arrays.asList(lowercase));
temp.addAll(Arrays.asList(capital));
temp.addAll(Arrays.asList(number));
}else if(type == TYPE.LETTER_CAPITAL_NUMBER_SIGN){
temp.addAll(Arrays.asList(lowercase));
temp.addAll(Arrays.asList(capital));
temp.addAll(Arrays.asList(number));
temp.addAll(Arrays.asList(sign));
}
for (int i = 0; i < num; i++) {
code.append(temp.get(random.nextInt(temp.size())));
}
return code.toString();
}
}
下面 前端吊起收营台 就可以了
支付页面