package com.example.api;
import com.alibaba.fastjson.JSONObject;
import com.example.utils.IpUtils;
import com.example.utils.StringUtils;
import com.example.utils.weixin.PayUtil;
import com.example.utils.weixin.config.WxPayConfig;
import com.example.utils.weixin.vo.OAuthJsToken;
import com.example.vo.Json;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.weixin4j.WeixinException;
import org.weixin4j.WeixinSupport;
import org.weixin4j.http.HttpsClient;
import org.weixin4j.http.Response;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
@RequestMapping("/weixin")
@RestController
public class WeixinController extends WeixinSupport{
private Logger logger = LoggerFactory.getLogger(getClass());
private static final String appid = "wx928e5147695c0ad3"; //APP应用appid
private static final String secret = "5b09aab1013e54c261373d2fe0f1fe16"; //APP应用密钥
private static final String grant_type = "authorization_code";
/**
* 使用code获取openid接口
*/
@RequestMapping("prepay")
public Map<String, Object> prepay(String code, HttpServletRequest request) throws WeixinException, IOException {
if (code == null || code.equals("")) {
throw new WeixinException("invalid null, code is null.");
}
Map<String, Object> ret = new HashMap<String, Object>();
//拼接参数
String param = "?grant_type=" + grant_type + "&appid=" + appid + "&secret=" + secret + "&js_code=" + code;
//创建请求对象
HttpsClient http = new HttpsClient();
//调用获取access_token接口
Response res = http.get("https://api.weixin.qq.com/sns/jscode2session" + param);
//根据请求结果判定,是否验证成功
JSONObject jsonObj = res.asJSONObject();
if (jsonObj != null) {
Object errcode = jsonObj.get("errcode");
if (errcode != null) {
//返回异常信息
throw new WeixinException(getCause(Integer.parseInt(errcode.toString())));
}
ObjectMapper mapper = new ObjectMapper();
OAuthJsToken oauthJsToken = mapper.readValue(jsonObj.toJSONString(),OAuthJsToken.class);
logger.info("openid=" + oauthJsToken.getOpenid());
ret.put("openid", oauthJsToken.getOpenid());
}
return ret;
}
/**
* 统一下单接口
*/
@RequestMapping("pay")
public Json pay(String money,HttpServletRequest request){
Json json = new Json();
try{
//生成的随机字符串
String nonce_str = StringUtils.getRandomStringByLength(32);
//商品名称
String body = "充值";
//附加数据
String attach = "支付";
//获取本机的ip地址
String spbill_create_ip = IpUtils.getIpAddr(request);
String orderNo = PayUtil.getRandomOrderId();
//String money = "1";//支付金额,单位:分,这边需要转成字符串类型,否则后面的签名会失败
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appid", WxPayConfig.appid);
packageParams.put("attach", attach);
packageParams.put("body", body);
packageParams.put("mch_id", WxPayConfig.mch_id);
packageParams.put("nonce_str", nonce_str);
packageParams.put("notify_url", WxPayConfig.notify_url);
packageParams.put("out_trade_no", orderNo);//商户订单号
packageParams.put("spbill_create_ip", spbill_create_ip);
packageParams.put("total_fee", money);//支付金额,这边需要转成字符串类型,否则后面的签名会失败
packageParams.put("trade_type", WxPayConfig.TRADETYPE);
//除去数组中的空值和签名参数
packageParams = PayUtil.paraFilter(packageParams);
String prestr = PayUtil.createLinkString(packageParams); //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
//MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
String mysign = PayUtil.sign(prestr, WxPayConfig.key, "utf-8").toUpperCase();
logger.info("=======================第一次签名:" + mysign + "=====================");
//拼接统一下单接口使用的xml数据,要将上一步生成的签名一起拼接进去
String xml = "<xml>" + "<appid>" + WxPayConfig.appid + "</appid>"
+ "<attach>" + attach + "</attach>"
+ "<body>" + body + "</body>"
+ "<mch_id>" + WxPayConfig.mch_id + "</mch_id>"
+ "<nonce_str>" + nonce_str + "</nonce_str>"
+ "<notify_url>" + WxPayConfig.notify_url + "</notify_url>"
+ "<out_trade_no>" + orderNo + "</out_trade_no>"
+ "<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>"
+ "<total_fee>" + money + "</total_fee>"
+ "<trade_type>" + WxPayConfig.TRADETYPE + "</trade_type>"
+ "<sign>" + mysign + "</sign>"
+ "</xml>";
System.out.println("调试模式_统一下单接口 请求XML数据:" + xml);
//调用统一下单接口并接受返回的结果
String result = PayUtil.httpRequest(WxPayConfig.pay_url, "POST", xml);
System.out.println("调试模式_统一下单接口 返回XML数据:" + result);
//将解析结果存储在HashMap中
Map map = PayUtil.doXMLParse(result);
String return_code = (String) map.get("return_code");//返回状态码
//返回给服务端需要的参数
Map<String, Object> response = new HashMap<String, Object>();
if(return_code == "SUCCESS" || return_code.equals(return_code)){
//业务结果
String prepay_id = (String) map.get("prepay_id");//返回的预付单信息
response.put("partnerid", WxPayConfig.mch_id);
response.put("prepayid", prepay_id);
response.put("noncestr", nonce_str);
response.put("package", "Sign=WXPay");
Long timestamp = System.currentTimeMillis() / 1000;
response.put("timestamp", timestamp + "");//这边要将返回的时间戳转化成字符串,不然应用端调用wx.requestPayment方法会报签名错误
//参数要按照顺序摆放
String stringSignTemp = "appid=" + WxPayConfig.appid + "&noncestr=" + nonce_str + "&package=" + "Sign=WXPay"+ "&partnerid=" + WxPayConfig.mch_id + "&prepayid="+prepay_id+ "×tamp=" + timestamp;
//再次签名
String sign = PayUtil.sign(stringSignTemp, WxPayConfig.key, "utf-8").toUpperCase();
logger.info("=======================第二次签名:" + sign + "=====================");
response.put("sign", sign);
//更新订单信息
//业务逻辑代码
}
response.put("appid", WxPayConfig.appid);
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
项目采用SpringBoot框架,可直接运行,更改WxPayConfig文件appid、mch_id、key、notify_url即可完成APP支付及回调功能。包含统一下单(支付接口)即WeixinController中pay方法、支付结果通知(回调接口)即WeixinController中notify方法
资源推荐
资源详情
资源评论




















收起资源包目录





































































































共 803 条
- 1
- 2
- 3
- 4
- 5
- 6
- 9
资源评论

- 一碗阳光干了2019-03-11大佬,pom文件报Missing artifact eid.sdk:eID.SDK.Service-froad:jar:0.1怎么回事?付士山哥2019-03-22删除对应的pom结点即可
- 小男孩丶2018-12-27退款可以分享下吗付士山哥2018-12-30这个目前还没写,可以根据下单然后生成的xml参照网上其他demo进行编写
- weixin_440842312018-12-26您好,退款的可以给分享一下么付士山哥2018-12-30这个目前还没写,可以根据下单然后生成的xml参照网上其他demo进行编写

付士山哥
- 粉丝: 14
- 资源: 3
上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


会员权益专享
安全验证
文档复制为VIP权益,开通VIP直接复制
