支付模块-下单接口

This commit is contained in:
2024-12-24 17:39:49 +08:00
parent b7eec65e6d
commit 27eac91d1c
21 changed files with 658 additions and 1 deletions

View File

@ -0,0 +1,246 @@
package com.fastbee.data.controller.pay;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.json.ObjectMapper;
import com.fastbee.common.core.controller.BaseController;
import com.fastbee.common.core.domain.AjaxResult;
import com.fastbee.common.utils.pay.AesUtil;
import com.fastbee.common.wechat.WeChatLoginBody;
import com.fastbee.rechargecard.domain.NgUserRechargeRecords;
import com.fastbee.rechargecard.domain.dto.RechargecardUser;
import com.fastbee.rechargecard.domain.dto.WeChatRecharge;
import com.fastbee.rechargecard.domain.dto.WeChatRechargeBacktracking;
import com.fastbee.rechargecard.service.INgUserRechargeRecordsService;
import com.fastbee.rechargecard.service.IUserConsumptionDetailsService;
import com.fastbee.rechargecard.service.IUserRechargeCardsService;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.client.utils.URIBuilder;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import com.fastbee.common.utils.pay.wxPayConfig;
import static cn.hutool.core.util.XmlUtil.xmlToMap;
import static com.fastbee.common.constant.Constants.LANGUAGE;
@Api(tags = "支付模块")
@Slf4j
@RestController
@RequestMapping("/pay")
public class WeChatPayController extends BaseController {
/** 商户号 */
public static String mchId = "1531795301";
/** 商户API私钥文件路径 */
public static String privateKeyPath = "fastbee-common/src/main/java/com/fastbee/common/utils/pay/apiclient_key.pem";
/** 商户API证书序列号 */
public static String serial_no = "3075B63EF52666EDC3EAFC5D4FB35C02CE123A9C";
/** 商户APIV3密钥 */
public static String apiV3Key = "e85a203e8ca146102f5cd7ecff912580";
//微信小程序appid
public static String appId="wx308612d2a8423311";
//请求随机串
public static String nonce_str="";
//时间戳
public static String timeStamp="";
// 使用HttpClientBuilder创建CloseableHttpClient实例采用默认配置
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
@Autowired
private INgUserRechargeRecordsService ngUserRechargeRecordsService;
@Autowired
private IUserRechargeCardsService userRechargeCardsService;
@Autowired
private IUserConsumptionDetailsService userConsumptionDetailsService;
/**
* 微信支付生成订单
* @return 登录结果
*/
@ApiOperation("生成订单")
@PostMapping("/order")
public AjaxResult BuildOrder(@RequestBody WeChatRecharge recharge) throws Exception {
String out_trade_no=UUID.randomUUID().toString().replace("-", "");
while(ngUserRechargeRecordsService.SelectRechargeRecodeByRechargeCode(out_trade_no) !=null)
{
out_trade_no=UUID.randomUUID().toString().replace("-", "");;
}
recharge.setRechargeCode(out_trade_no);
Map<String,String> result=CreateOrder(recharge);//生成订单
if(result.isEmpty())
{
return toAjax("微信支付订单生成失败");
}
//订单生成成功
int flag=ngUserRechargeRecordsService.insertNgUserRechargeRecordsWeChat(recharge);//插入用户充值记录表
flag=userConsumptionDetailsService.insertUserConsumptionDetailsWechat(recharge);//插入用户消费明细表
if(flag==1)
{
return success(result);
}
return toAjax("系统内部订单生成失败");
}
@PostMapping("/getresult")
@ApiOperation("支付通知结果回溯")
@ResponseBody
public String getResult(@RequestBody WeChatRechargeBacktracking backtracking) throws Exception {
String algorithm=backtracking.getResource().getAlgorithm();
String nonce=backtracking.getResource().getNonce();
String associated_data=backtracking.getResource().getAssociated_data();
String cliphertext=backtracking.getResource().getCliphertext();
AesUtil aesUtil=new AesUtil(apiV3Key.getBytes("utf-8"));
//解密后的值
String decryptKey=aesUtil.decryptToString(associated_data.getBytes("utf-8"),nonce.getBytes("utf-8"),cliphertext);
System.out.println("解密后的:"+decryptKey);
return decryptKey;
}
/**
* 创建订单获取prepay_id和paySign
* @param recharge
* @return
* @throws Exception
*/
public Map<String, String> CreateOrder(WeChatRecharge recharge) throws Exception{
System.out.println("CreateOrder");
//请求URL
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
Map<String,String> result=new HashMap<>();
Map<String,Object> reqdata=new HashMap<String,Object>();
Map<String,Object> amount=new HashMap<>();
Map<String,Object> payer=new HashMap<>();
amount.put("total",recharge.getTotal());
amount.put("currency",recharge.getCurrency());
payer.put("openid",recharge.getOpenId());
reqdata.put("amount",amount);
reqdata.put("appid",appId);
reqdata.put("mchid",mchId);
reqdata.put("description",recharge.getCardnumber()+recharge.getAmount().toString());
reqdata.put("out_trade_no",recharge.getRechargeCode());
reqdata.put("notify_url","https://1481109f.r3.cpolar.cn/pay/getresult");
reqdata.put("payer",payer);
String Signature=getSign(reqdata);
result.put("paySign",Signature);
String Authorization="WECHATPAY2-SHA256-RSA2048 mchid=\""+mchId+"\",nonce_str=\""+nonce_str+"\",signature=\""+Signature+"\",timestamp=\""+timeStamp+"\",serial_no=\""+serial_no+"\"";
StringEntity entity = new StringEntity(JSONUtil.toJsonStr(reqdata), "utf-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Authorization",Authorization);
//完成签名并执行请求
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200) {
// 假设responseEntity是包含JSON响应的字符串
String responseEntity = EntityUtils.toString(response.getEntity());
// 使用Hutool的JSONUtil解析JSON字符串
JSONObject jsonObject = JSONUtil.parseObj(responseEntity);
// 安全地获取prepay_id的值
String prepayId = jsonObject.getStr("prepay_id");
System.out.println("Prepay ID: " + prepayId);
result.put("prepay_id",prepayId);
System.out.println("success,return body = " + prepayId);
return result;
} else if (statusCode == 204) {
return null;
} else {
System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
throw new IOException("request failed");
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
response.close();
httpClient.close();
}
}
/**
* 生成签名
*/
public String getSign(Map<String,Object> reqBody) throws Exception {
//获取时间戳
String reqMethod="POST";
String url="/v3/pay/transactions/jsapi";
/*String reqMethod="GET";
String url="/v3/refund/domestic/refunds/123123123123";*/
timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
//timeStamp="1554208460";
nonce_str= UUID.randomUUID().toString();
//nonce_str="593BEC0C930BF1AFEB40B4A08C8FB242";
String reqParam= JSONUtil.toJsonStr(reqBody);
/*HTTP请求方法\n
URL\n
请求时间戳\n
请求随机串\n
请求报文主体\n
*/
String signStr=reqMethod+"\n"+url+"\n"+timeStamp+"\n"+nonce_str+"\n"+reqParam +"\n";
//String signStr=reqMethod+"\n"+url+"\n"+timeStamp+"\n"+nonce_str+"\n\n";
String sign=sign(signStr.getBytes("utf-8"));
/*//进行sha256
String sha256HexSignStr = DigestUtil.sha256Hex(signStr);
//在进行base64
String base64SignStr = Base64.getEncoder().encodeToString(sha256HexSignStr.getBytes());
*/
return sign;
}
/**
* 生成签名方法
* @param message
* @return
* @throws Exception
*/
private String sign(byte[] message) throws Exception{
Signature sign;
sign = Signature.getInstance("SHA256withRSA");
//这里需要一个PrivateKey类型的参数就是商户的私钥。
//获取商户私钥——传商户私钥位置
PrivateKey privateKey = wxPayConfig.getPrivateKey(privateKeyPath);
sign.initSign(privateKey);
sign.update(message);
return Base64.getEncoder().encodeToString(sign.sign());
}
}

View File

@ -36,7 +36,6 @@ public class UserRechargeController extends BaseController {
@ApiOperation("修改用户充值卡")
public AjaxResult result(@RequestBody RechargecardUser rechargecardUser)
{
return toAjax(userRechargeCardsService.updateUserRecharge(rechargecardUser));
}
}