修改微信公众号信息
This commit is contained in:
parent
d9808f2ca5
commit
ab756cda3d
|
@ -1,150 +0,0 @@
|
|||
package com.nu.modules.wechart.controller;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.nu.modules.wechart.entity.WechatpayConfig;
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/weiXinPay2")
|
||||
@Slf4j
|
||||
public class WechatPay2Controller {
|
||||
@Autowired
|
||||
public WechatpayConfig wechatpayConfig;
|
||||
|
||||
|
||||
/**
|
||||
* Native下单
|
||||
* 调用统一下单API,生成支付二维码
|
||||
*/
|
||||
@PostMapping("/native")
|
||||
public Map<String,String> nativePay() throws Exception {
|
||||
// log.info("生成订单");
|
||||
// //生成订单
|
||||
// log.info("存入数据库...");
|
||||
//
|
||||
// log.info("调用统一下单API");
|
||||
// // 订单号
|
||||
// String orderNo = IdUtil.simpleUUID();
|
||||
// // 请求body参数 看官方文档
|
||||
// WXConfig config = new WXConfig();
|
||||
// config.setAppId(wechatpayConfig.getAppid());
|
||||
// config.setMchId(wechatpayConfig.getMchId());
|
||||
// config.setKey(wechatpayConfig.getApiV3Key());
|
||||
//
|
||||
// Map<String, String> paramsMap = new HashMap<>();
|
||||
// paramsMap.put("appid", wechatpayConfig.getAppid());
|
||||
// paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||
// paramsMap.put("description", "测试微信jsapi支付");
|
||||
// paramsMap.put("out_trade_no", orderNo);
|
||||
// // 回调的地址
|
||||
// paramsMap.put("notify_url",wechatpayConfig.getNotifyDomain()+"/native/notify");
|
||||
//
|
||||
// Map amountMap = new HashMap();
|
||||
// //订单总金额,单位为分。
|
||||
// amountMap.put("total", 1);
|
||||
// //CNY:人民币,境内商户号仅支持人民币。
|
||||
// amountMap.put("currency", "CNY");
|
||||
// paramsMap.put("total_fee", 1+"");
|
||||
//// paramsMap.put("amount", amountMap.toString());
|
||||
// Map payer = new HashMap();
|
||||
// payer.put("openid", "oE3S76LTNliVGdi63ciiV9T2pqAU");
|
||||
// paramsMap.put("payer", payer.toString());
|
||||
// paramsMap.put("trade_type", "JSAPI");
|
||||
// String generateNonceStr = WXPayUtil.generateNonceStr();
|
||||
// paramsMap.put("nonce_str", generateNonceStr);
|
||||
//
|
||||
// String body = "护理单元";
|
||||
// paramsMap.put("body", body);
|
||||
//
|
||||
// log.info("请求参数1:" + paramsMap.toString());
|
||||
//
|
||||
// Set<String> keySet = paramsMap.keySet();
|
||||
// String[] keyArray = (String[])keySet.toArray(new String[keySet.size()]);
|
||||
// Arrays.sort(keyArray);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// String[] var6 = keyArray;
|
||||
// int var7 = keyArray.length;
|
||||
//
|
||||
// for(int var8 = 0; var8 < var7; ++var8) {
|
||||
// String k = var6[var8];
|
||||
// if (!k.equals("sign") && ((String)paramsMap.get(k)).trim().length() > 0) {
|
||||
// sb.append(k).append("=").append(((String)paramsMap.get(k)).trim()).append("&");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// sb.append("key=").append( wechatpayConfig.getApiV3Key());
|
||||
// log.info("xml1:" + sb.toString());
|
||||
//
|
||||
// String xml2 = WXPayUtil.mapToXml(paramsMap);
|
||||
// log.info("xml2:" + xml2);
|
||||
//
|
||||
// String sign = WXPayUtil.generateSignature(paramsMap, wechatpayConfig.getApiV3Key(), WXPayConstants.SignType.MD5);
|
||||
// log.info("sign:" + sign);
|
||||
// paramsMap.put("sign", sign);
|
||||
//
|
||||
// log.info("请求参数2:" + paramsMap);
|
||||
//
|
||||
// WXPay wxpay = new WXPay(config);
|
||||
// Map<String, String> response = wxpay.unifiedOrder(paramsMap);
|
||||
// for (String key : response.keySet()) {
|
||||
// log.info("微信支付订单微信返回参数:keys:" + key + " value:" + response.get(key).toString());
|
||||
// }
|
||||
// return null;
|
||||
|
||||
Config config =
|
||||
new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(wechatpayConfig.getMchId())
|
||||
.privateKeyFromPath(wechatpayConfig.getPrivateKeyPath())
|
||||
.merchantSerialNumber(wechatpayConfig.getMchSerialNo())
|
||||
.apiV3Key(wechatpayConfig.getApiV3Key())
|
||||
.build();
|
||||
// 构建service
|
||||
JsapiService service = new JsapiService.Builder().config(config).build();
|
||||
// request.setXxx(val)设置所需参数,具体参数可见Request定义
|
||||
PrepayRequest request = new PrepayRequest();
|
||||
Amount amount = new Amount();
|
||||
amount.setTotal(1);
|
||||
request.setAmount(amount);
|
||||
request.setAppid(wechatpayConfig.getAppid());
|
||||
request.setMchid(wechatpayConfig.getMchId());
|
||||
request.setDescription("测试商品标题");
|
||||
request.setNotifyUrl(wechatpayConfig.getNotifyDomain());
|
||||
request.setOutTradeNo(IdUtil.simpleUUID());
|
||||
Payer payer = new Payer();
|
||||
payer.setOpenid("oE3S76LTNliVGdi63ciiV9T2pqAU");
|
||||
request.setPayer(payer);
|
||||
// 调用下单方法,得到应答
|
||||
PrepayResponse response = service.prepay(request);
|
||||
log.info("prepayId:" + response.getPrepayId());
|
||||
Map map = prepayWithRequestPayment(request);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回调起支付的参数
|
||||
* @return
|
||||
*/
|
||||
private Map<String,String> prepayWithRequestPayment(PrepayRequest request){
|
||||
Map<String,String> map = new HashMap<>();
|
||||
JsapiServiceExtension jse = new JsapiServiceExtension.Builder().build();
|
||||
PrepayWithRequestPaymentResponse response = jse.prepayWithRequestPayment(request);
|
||||
map.put("appId",response.getAppId());
|
||||
map.put("timeStamp",response.getTimeStamp());
|
||||
map.put("nonceStr",response.getNonceStr());
|
||||
map.put("package",response.getPackageVal());
|
||||
map.put("signType",response.getSignType());
|
||||
map.put("paySign",response.getPaySign());
|
||||
return map;
|
||||
}
|
||||
}
|
|
@ -1,35 +1,57 @@
|
|||
package com.nu.modules.wechart.controller;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.github.wxpay.sdk.WXPayUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.nu.modules.bizEmployeesInfo.entity.BizEmployeesInfo;
|
||||
import com.nu.modules.wechart.entity.WechatpayConfig;
|
||||
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
|
||||
import com.wechat.pay.java.core.Config;
|
||||
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
|
||||
|
||||
import com.wechat.pay.java.core.exception.ServiceException;
|
||||
import com.wechat.pay.java.core.notification.NotificationConfig;
|
||||
import com.wechat.pay.java.core.notification.NotificationParser;
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
|
||||
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
|
||||
import com.wechat.pay.java.service.payments.jsapi.model.*;
|
||||
import com.wechat.pay.java.service.payments.model.Transaction;
|
||||
import io.swagger.models.auth.In;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.http.HttpEntity;
|
||||
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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.wechat.pay.java.core.notification.RequestParam;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/weiXinPay")
|
||||
@Slf4j
|
||||
public class WechatPayController {
|
||||
|
||||
|
||||
@Resource
|
||||
@Autowired
|
||||
public WechatpayConfig wechatpayConfig;
|
||||
|
||||
|
||||
|
@ -38,308 +60,238 @@ public class WechatPayController {
|
|||
* 调用统一下单API,生成支付二维码
|
||||
*/
|
||||
@PostMapping("/native")
|
||||
public Map<String,String> nativePay() throws Exception {
|
||||
log.info("生成订单");
|
||||
//生成订单
|
||||
log.info("存入数据库...");
|
||||
public Map<String,String> nativePay(@RequestBody Map<String,String> params) throws Exception {
|
||||
|
||||
log.info("调用统一下单API");
|
||||
//调用统一下单API
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
|
||||
Config config =
|
||||
new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(wechatpayConfig.getMchId())
|
||||
.privateKeyFromPath(wechatpayConfig.getPrivateKeyPath())
|
||||
.merchantSerialNumber(wechatpayConfig.getMchSerialNo())
|
||||
.apiV3Key(wechatpayConfig.getApiV3Key())
|
||||
.build();
|
||||
// 构建service
|
||||
JsapiService service = new JsapiService.Builder().config(config).build();
|
||||
PrepayRequest request = new PrepayRequest();
|
||||
String title = params.get("title");
|
||||
String openId = params.get("openId");
|
||||
String amountPrice = params.get("amountPrice");
|
||||
|
||||
// 订单号
|
||||
String orderNo = IdUtil.simpleUUID();
|
||||
// 请求body参数 看官方文档
|
||||
Map paramsMap = new HashMap();
|
||||
paramsMap.put("appid", wechatpayConfig.getAppid());
|
||||
paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||
paramsMap.put("description", "iPhone 15 Pro Max 5G");
|
||||
paramsMap.put("out_trade_no", orderNo);
|
||||
// 回调的地址
|
||||
paramsMap.put("notify_url",wechatpayConfig.getNotifyDomain()+"/native/notify");
|
||||
Map amountMap = new HashMap();
|
||||
//订单总金额,单位为分。
|
||||
amountMap.put("total", 1);
|
||||
//CNY:人民币,境内商户号仅支持人民币。
|
||||
amountMap.put("currency", "CNY");
|
||||
|
||||
paramsMap.put("amount", amountMap);
|
||||
|
||||
|
||||
|
||||
//将参数转换成json字符串
|
||||
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||
log.info("请求参数:" + jsonParams);
|
||||
|
||||
StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
||||
entity.setContentType("application/json");
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Accept", "application/json");
|
||||
httpPost.setHeader("Authorization", "WECHATPAY2-SHA256-RSA2048 "+ jsonParams);
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||
try {
|
||||
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
|
||||
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||
if (statusCode == 200) { //处理成功
|
||||
log.info("成功, 返回结果 = " + bodyAsString);
|
||||
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||
log.info("成功");
|
||||
} else {
|
||||
log.info("Native下单失败,响应码 = " + statusCode+ ",返回结果 = " +
|
||||
bodyAsString);
|
||||
throw new IOException("request failed");
|
||||
}
|
||||
//响应结果
|
||||
Map<String, String> resultMap = JSONUtil.toBean(bodyAsString,HashMap.class);
|
||||
//二维码
|
||||
String codeUrl = resultMap.get("code_url");
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put("codeUrl", codeUrl);
|
||||
map.put("orderNo", orderNo.toString());
|
||||
Amount amount = new Amount();
|
||||
amount.setTotal(Integer.parseInt(amountPrice));
|
||||
request.setAmount(amount);
|
||||
request.setAppid(wechatpayConfig.getAppid());
|
||||
request.setMchid(wechatpayConfig.getMchId());
|
||||
request.setDescription(title);
|
||||
request.setNotifyUrl(wechatpayConfig.getNotifyDomain());
|
||||
request.setOutTradeNo(IdUtil.simpleUUID());
|
||||
Payer payer = new Payer();
|
||||
payer.setOpenid(openId);
|
||||
request.setPayer(payer);
|
||||
// 调用下单方法,得到应答
|
||||
PrepayResponse response = service.prepay(request);
|
||||
log.info("prepayId:" + response.getPrepayId());
|
||||
Map map = prepayWithRequestPayment(request,config);
|
||||
return map;
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 支付通知
|
||||
* 微信支付通过支付通知接口将用户支付成功消息通知给商户
|
||||
* 返回调起支付的参数
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/native/notify")
|
||||
public Map<String,String> nativeNotify(@RequestBody Map<String,Object> signalRes, HttpServletResponse response){
|
||||
Map<String, String> map = new HashMap<>();//应答对象
|
||||
log.info("支付通知的完整数据 ===> {}", signalRes);
|
||||
try {
|
||||
//用密文解密出明文
|
||||
Map<String,String> resource=(Map<String,String>)signalRes.get("resource");
|
||||
String ciphertext=resource.get("ciphertext");
|
||||
String associatedData=resource.get("associated_data");
|
||||
String nonce=resource.get("nonce");
|
||||
// 拿到明文
|
||||
String plainText=new AesUtil(wechatpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);
|
||||
//转换
|
||||
HashMap<String,Object> data= JSONUtil.toBean(plainText,HashMap.class);
|
||||
log.info("解密后的完整数据:{}",data);
|
||||
//处理订单
|
||||
log.info("处理订单...");
|
||||
//成功应答:成功应答必须为200或204,否则就是失败应答
|
||||
response.setStatus(200);
|
||||
map.put("code", "SUCCESS");
|
||||
} catch (GeneralSecurityException e) {
|
||||
response.setStatus(500);
|
||||
map.put("code", "FAIL");
|
||||
map.put("message","失败");
|
||||
}
|
||||
private Map<String,String> prepayWithRequestPayment(PrepayRequest request,Config config){
|
||||
Map<String,String> map = new HashMap<>();
|
||||
JsapiServiceExtension jse = new JsapiServiceExtension.Builder().config(config).build();
|
||||
PrepayWithRequestPaymentResponse response = jse.prepayWithRequestPayment(request);
|
||||
map.put("appId",response.getAppId());
|
||||
map.put("timeStamp",response.getTimeStamp());
|
||||
map.put("nonceStr",response.getNonceStr());
|
||||
map.put("package",response.getPackageVal());
|
||||
map.put("signType",response.getSignType());
|
||||
map.put("paySign",response.getPaySign());
|
||||
return map;
|
||||
}
|
||||
@PostMapping("/callback")
|
||||
public String courseNative(HttpServletRequest request, HttpServletResponse response) {
|
||||
|
||||
System.out.println("11111111111111");
|
||||
NotificationConfig config =
|
||||
new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(wechatpayConfig.getMchId())
|
||||
.apiV3Key(wechatpayConfig.getApiV3Key())
|
||||
.merchantSerialNumber(wechatpayConfig.getMchSerialNo())
|
||||
.privateKeyFromPath(wechatpayConfig.getPrivateKeyPath())
|
||||
.build();
|
||||
System.out.println("222222222222222"+config);
|
||||
// 从请求头中获取信息
|
||||
String timestamp = request.getHeader("Wechatpay-Timestamp");
|
||||
String nonce = request.getHeader("Wechatpay-Nonce");
|
||||
String signature = request.getHeader("Wechatpay-Signature");
|
||||
String singType = request.getHeader("Wechatpay-Signature-Type");
|
||||
String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");
|
||||
|
||||
System.out.println("333333333333333");
|
||||
String requestBody = getRequestBody(request);
|
||||
|
||||
System.out.println("333333333333333"+requestBody);
|
||||
// 初始化解析器 NotificationParser
|
||||
NotificationParser parser = new NotificationParser(config);
|
||||
System.out.println("444444444444444444444" + parser);
|
||||
RequestParam requestParam = new RequestParam.Builder()
|
||||
.serialNumber(wechatPayCertificateSerialNumber)
|
||||
.nonce(nonce)
|
||||
.signature(signature)
|
||||
.timestamp(timestamp)
|
||||
.signType(singType)
|
||||
.body(requestBody)
|
||||
.build();
|
||||
System.out.println("555555555555555555555" + requestParam);
|
||||
try {
|
||||
// 这个Transaction是微信包里面的
|
||||
Transaction decryptObject = parser.parse( requestParam, Transaction.class);
|
||||
|
||||
System.out.println("666666666666666666:"+decryptObject);
|
||||
return decryptObject.getTradeState().toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
// 获取请求头里的数据
|
||||
private String getRequestBody(HttpServletRequest request) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
try (
|
||||
ServletInputStream inputStream = request.getInputStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("读取数据流异常:"+e);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
/**
|
||||
* 查询订单
|
||||
* @param orderNo
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@GetMapping("/query/{orderNo}")
|
||||
public String queryOrder(@PathVariable String orderNo) throws Exception {
|
||||
log.info("查询订单");
|
||||
String url = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s", orderNo);
|
||||
url = url+"?mchid="+wechatpayConfig.getMchId();
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setHeader("Accept", "application/json");
|
||||
@PostMapping("/queryOrderById")
|
||||
public Map<String,Object> queryOrderById(@RequestBody Map<String,String> params) throws Exception {
|
||||
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpGet);
|
||||
try {
|
||||
String bodyAsString = EntityUtils.toString(response.getEntity());//响应体
|
||||
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||
if (statusCode == 200) { //处理成功
|
||||
log.info("成功, 返回结果 = " + bodyAsString);
|
||||
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||
log.info("成功");
|
||||
} else {
|
||||
log.info("查单接口调用,响应码 = " + statusCode+ ",返回结果 = " + bodyAsString);
|
||||
throw new IOException("request failed");
|
||||
|
||||
|
||||
Config config =
|
||||
new RSAAutoCertificateConfig.Builder()
|
||||
.merchantId(wechatpayConfig.getMchId())
|
||||
.privateKeyFromPath(wechatpayConfig.getPrivateKeyPath())
|
||||
.merchantSerialNumber(wechatpayConfig.getMchSerialNo())
|
||||
.apiV3Key(wechatpayConfig.getApiV3Key())
|
||||
.build();
|
||||
String prepay_id = params.get("prepay_id");
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
if(StringUtils.isEmpty(prepay_id)){
|
||||
map.put("code","400");
|
||||
map.put("msg","参数错误,prepay_id为空!");
|
||||
return map;
|
||||
}
|
||||
return bodyAsString;
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 用户取消订单
|
||||
* @param orderNo 订单id
|
||||
*/
|
||||
@PostMapping("/cancel/{orderNo}")
|
||||
public String cancel(@PathVariable String orderNo) throws Exception {
|
||||
log.info("用户取消订单");
|
||||
//创建远程请求对象
|
||||
String url = String.format("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s/close", orderNo);
|
||||
HttpPost httpPost = new HttpPost(url);
|
||||
|
||||
//组装json请求体
|
||||
Map<String, String> paramsMap = new HashMap<>();
|
||||
paramsMap.put("mchid", wechatpayConfig.getMchId());
|
||||
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||
log.info("请求参数 ===> {}", jsonParams);
|
||||
|
||||
//将请求参数设置到请求对象中
|
||||
StringEntity entity = new StringEntity(jsonParams,"utf-8");
|
||||
entity.setContentType("application/json");
|
||||
httpPost.setEntity(entity);
|
||||
httpPost.setHeader("Accept", "application/json");
|
||||
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||
try {
|
||||
int statusCode = response.getStatusLine().getStatusCode();//响应状态码
|
||||
if (statusCode == 200) { //处理成功
|
||||
log.info("成功200");
|
||||
} else if (statusCode == 204) { //处理成功,无返回Body
|
||||
log.info("成功204");
|
||||
} else {
|
||||
log.info("Native下单失败,响应码 = " + statusCode);
|
||||
throw new IOException("request failed");
|
||||
}
|
||||
return "订单取消成功";
|
||||
} finally {
|
||||
response.close();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 申请退款
|
||||
* @param orderNo 订单编号
|
||||
*/
|
||||
@PostMapping("/refunds/{orderNo}")
|
||||
public Map<String,Object> refunds(@PathVariable String orderNo) throws Exception {
|
||||
|
||||
log.info("创建退款单记录...");
|
||||
//根据订单编号创建退款单
|
||||
|
||||
log.info("调用退款API");
|
||||
|
||||
//调用统一下单API
|
||||
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");
|
||||
|
||||
// 请求body参数
|
||||
Map paramsMap = new HashMap();
|
||||
paramsMap.put("out_trade_no", orderNo);//订单编号
|
||||
|
||||
// 给它一个退款单号
|
||||
paramsMap.put("out_refund_no", "tk202412120001");//退款单编号
|
||||
paramsMap.put("reason", "买了不发货");//退款原因
|
||||
paramsMap.put("notify_url", wechatpayConfig.getNotifyDomain()+"/refunds/notify");//退款通知地址
|
||||
|
||||
Map amountMap = new HashMap();
|
||||
amountMap.put("refund", 1);//退款金额
|
||||
amountMap.put("total", 1);//原订单金额
|
||||
amountMap.put("currency", "CNY");//退款币种
|
||||
paramsMap.put("amount", amountMap);
|
||||
|
||||
//将参数转换成json字符串
|
||||
String jsonParams = JSONUtil.toJsonStr(paramsMap);
|
||||
log.info("请求参数 ===> {}" + jsonParams);
|
||||
|
||||
StringEntity entity = new StringEntity(jsonParams, "utf-8");
|
||||
entity.setContentType("application/json");//设置请求报文格式
|
||||
httpPost.setEntity(entity);//将请求报文放入请求对象
|
||||
httpPost.setHeader("Accept", "application/json");//设置响应报文格式
|
||||
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||
//完成签名并执行请求,并完成验签
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpPost);
|
||||
// 构建service
|
||||
JsapiService service = new JsapiService.Builder().config(config).build();
|
||||
QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
|
||||
queryRequest.setMchid(wechatpayConfig.getMchId());
|
||||
queryRequest.setTransactionId(prepay_id);
|
||||
|
||||
try {
|
||||
//解析响应结果
|
||||
String bodyAsString = EntityUtils.toString(response.getEntity());
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode == 200) {
|
||||
log.info("成功, 退款返回结果 = " + bodyAsString);
|
||||
} else if (statusCode == 204) {
|
||||
log.info("成功");
|
||||
} else {
|
||||
throw new RuntimeException("退款异常, 响应码 = " + statusCode + ", 退款返回结果 = " + bodyAsString);
|
||||
Transaction result = service.queryOrderById(queryRequest);
|
||||
System.out.println(result.getTradeState());
|
||||
map.put("code","200");
|
||||
map.put("msg",result);
|
||||
} catch (ServiceException e) {
|
||||
// API返回失败, 例如ORDER_NOT_EXISTS
|
||||
System.out.printf("code=[%s], message=[%s]\n", e.getErrorCode(), e.getErrorMessage());
|
||||
System.out.printf("reponse body=[%s]\n", e.getResponseBody());
|
||||
}
|
||||
log.info("更新订单状态......");
|
||||
log.info("更新退款单......");
|
||||
return JSONUtil.toBean(bodyAsString,Map.class);
|
||||
} finally {
|
||||
response.close();
|
||||
return map;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 退款结果通知
|
||||
* 退款状态改变后,微信会把相关退款结果发送给商户。
|
||||
*/
|
||||
@PostMapping("/refunds/notify")
|
||||
public String refundsNotify(@RequestBody Map<String,Object> signalRes, HttpServletResponse response){
|
||||
log.info("退款通知执行");
|
||||
Map<String, String> map = new HashMap<>();//应答对象
|
||||
try {
|
||||
Map<String,String> resource=(Map<String,String>)signalRes.get("resource");
|
||||
String ciphertext=resource.get("ciphertext");
|
||||
String associatedData=resource.get("associated_data");
|
||||
String nonce=resource.get("nonce");
|
||||
// 拿到明文
|
||||
String plainText=new AesUtil(wechatpayConfig.getApiV3Key().getBytes(StandardCharsets.UTF_8)).decryptToString(associatedData.getBytes(StandardCharsets.UTF_8),nonce.getBytes(StandardCharsets.UTF_8),ciphertext);
|
||||
|
||||
//转换
|
||||
HashMap<String,Object> data= JSONUtil.toBean(plainText,HashMap.class);
|
||||
log.info("解密后的完整数据:{}",data);
|
||||
log.info("处理退款单................................");
|
||||
log.info("更新订单状态................................");
|
||||
|
||||
//成功应答
|
||||
response.setStatus(200);
|
||||
map.put("code", "SUCCESS");
|
||||
map.put("message", "成功");
|
||||
return JSONUtil.toJsonStr(map);
|
||||
} catch (Exception e) {
|
||||
|
||||
public static final String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";// 获取access
|
||||
|
||||
// 获取token
|
||||
public static String getToken(String apiurl, String appid, String secret)
|
||||
{
|
||||
String turl = String.format(
|
||||
"%s?grant_type=client_credential&appid=%s&secret=%s", apiurl,
|
||||
appid, secret);
|
||||
System.out.println("turl:" + turl);
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpGet get = new HttpGet(turl);
|
||||
System.out.println("get:" + get);
|
||||
JsonParser jsonparer = new JsonParser();// 初始化解析json格式的对象
|
||||
String result = null;
|
||||
try
|
||||
{
|
||||
HttpResponse res = client.execute(get);
|
||||
System.out.println("res:" + res);
|
||||
String responseContent = null; // 响应内容
|
||||
HttpEntity entity = res.getEntity();
|
||||
System.out.println("entity:" + entity);
|
||||
responseContent = EntityUtils.toString(entity, "UTF-8");
|
||||
JsonObject json = jsonparer.parse(responseContent)
|
||||
.getAsJsonObject();
|
||||
System.out.println("json:" + json);
|
||||
// 将json字符串转换为json对象
|
||||
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
|
||||
{
|
||||
if (json.get("errcode") != null)
|
||||
{// 错误时微信会返回错误码等信息,{"errcode":40013,"errmsg":"invalid appid"}
|
||||
}
|
||||
else
|
||||
{// 正常情况下{"access_token":"ACCESS_TOKEN","expires_in":7200}
|
||||
result = json.get("access_token").getAsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
//失败应答
|
||||
response.setStatus(500);
|
||||
map.put("code", "ERROR");
|
||||
map.put("message", "失败");
|
||||
return JSONUtil.toJsonStr(map);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 查询退款
|
||||
* @param refundNo 退款订单
|
||||
*/
|
||||
@GetMapping("/query-refund/{refundNo}")
|
||||
public String queryRefund(@PathVariable String refundNo) throws Exception {
|
||||
|
||||
log.info("查询退款接口调用 ===> {}", refundNo);
|
||||
String url = String.format("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s", refundNo);
|
||||
//创建远程Get 请求对象
|
||||
HttpGet httpGet = new HttpGet(url);
|
||||
httpGet.setHeader("Accept", "application/json");
|
||||
//创建httpclient对象
|
||||
CloseableHttpClient wxPayClient = HttpClients.createDefault();
|
||||
//完成签名并执行请求
|
||||
CloseableHttpResponse response = wxPayClient.execute(httpGet);
|
||||
try {
|
||||
String bodyAsString = EntityUtils.toString(response.getEntity());
|
||||
int statusCode = response.getStatusLine().getStatusCode();
|
||||
if (statusCode == 200) {
|
||||
log.info("成功, 查询退款返回结果 = " + bodyAsString);
|
||||
} else if (statusCode == 204) {
|
||||
log.info("成功");
|
||||
} else {
|
||||
throw new RuntimeException("查询退款异常, 响应码 = " + statusCode+ ", 查询退款返回结果 = " + bodyAsString);
|
||||
}
|
||||
return bodyAsString;
|
||||
} finally {
|
||||
response.close();
|
||||
finally
|
||||
{
|
||||
// 关闭连接 ,释放资源
|
||||
client.getConnectionManager().shutdown();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/getUserInfo")
|
||||
public JSONObject getWxUserInfo(@RequestBody Map<String,String> params) throws Exception {
|
||||
// String accessToken = getToken(GET_TOKEN_URL, "wx8fc3e4305d2fbf0b", "3bf3dd4ec72f591432db6b28c2c044e5");// 获取token
|
||||
String accessToken = params.get("access_token");
|
||||
String openid = params.get("openid");
|
||||
System.out.println("---------token-------"+accessToken);
|
||||
// 构造请求URL
|
||||
String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
|
||||
|
||||
// 发送HTTP请求,并获取返回结果
|
||||
HttpGet httpGet = new HttpGet(requestUrl);
|
||||
System.out.println("---------httpGet-------"+httpGet);
|
||||
CloseableHttpClient httpClient = HttpClients.createDefault();
|
||||
System.out.println("---------httpClient-------"+httpClient);
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(httpGet);
|
||||
System.out.println("---------httpResponse-------"+httpResponse);
|
||||
HttpEntity httpEntity = httpResponse.getEntity();
|
||||
System.out.println("---------httpEntity-------"+httpEntity);
|
||||
String responseJson = EntityUtils.toString(httpEntity, "UTF-8");
|
||||
System.out.println("---------responseJson-------"+responseJson);
|
||||
// 解析返回结果,获取手机号
|
||||
JSONObject jsonObject = new JSONObject(responseJson);
|
||||
System.out.println("---------jsonObject-------"+jsonObject);
|
||||
return jsonObject;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,6 +385,6 @@ wxpay:
|
|||
# 商户API证书序列号
|
||||
mch-serial-no: 3E51C9D24F64CE50E9273E544561D29684AB21C7
|
||||
# 接收结果通知地址
|
||||
notify-domain: http://r2agtr.natappfree.cc
|
||||
notify-domain: https://www.focusnu.com/nursing-unit_0010507/weiXinPay/wx/callback
|
||||
# 商户私钥文件路径
|
||||
private-key-path: c://apiclient_key.pem
|
|
@ -372,3 +372,18 @@ tplink:
|
|||
username: administrator
|
||||
password: Root@123..
|
||||
uploadpath: /
|
||||
|
||||
# 微信支付
|
||||
wxpay:
|
||||
# APIv3密钥
|
||||
api-v3-key: asdfiuzwe3534565478WETDSAFRWEq1E
|
||||
# APPID
|
||||
appid: wx8fc3e4305d2fbf0b
|
||||
# 商户ID
|
||||
mch-id: 1717618860
|
||||
# 商户API证书序列号
|
||||
mch-serial-no: 3E51C9D24F64CE50E9273E544561D29684AB21C7
|
||||
# 接收结果通知地址
|
||||
notify-domain: https://www.focusnu.com/nursing-unit_0010507/weiXinPay/callback
|
||||
# 商户私钥文件路径
|
||||
private-key-path: /opt/nu001/apiclient_key.pem
|
Loading…
Reference in New Issue