vue springboot 接入支付宝 微信 银联
程序员文章站
2024-01-22 11:11:10
...
需要:支付宝商户号,微信商户号,银联商户号
支付宝
- 进入支付宝开放平台,我用的公钥证书方式,参考文档… 把需要的6个文件弄到,
2.弄到文件后,后台yml配置文件中配置支付宝的一些参数和路径:
3.Controller 那边接收参数传给Service就行 自己写吧
4.Service:
//pom.xml引入支付宝sdk
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.8.62.ALL</version>
</dependency>
=====================================================================================
//支付
public String Alipay(FinalParma finalParma,int isMobile) {
try{CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl(gaturl);
certAlipayRequest.setAppId(appid);
certAlipayRequest.setPrivateKey(app_private_key);
certAlipayRequest.setFormat("json");
certAlipayRequest.setCharset(charset);
certAlipayRequest.setSignType(sign_type);
certAlipayRequest.setCertPath(app_cert_path);
certAlipayRequest.setAlipayPublicCertPath(ali_cert_path);
certAlipayRequest.setRootCertPath(ali_root_cert_path);
AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
if(isMobile==1){
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setReturnUrl(ali_return_url); //前台通知地址
request.setNotifyUrl(natapp + ali_notify_url); //异步地址
request.setBizContent(GsonUtil.getgson().toJson(finalParma));//这个就不解释了
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
if(response.isSuccess()){
System.out.println("调用手机支付成功");
return response.getBody(); //返回的是html文本
}else {
System.out.println("调用手机支付失败");
}
}else {
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(ali_return_url);
request.setNotifyUrl(natapp + ali_notify_url);
request.setBizContent(GsonUtil.getgson().toJson(finalParma));
AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
if(response.isSuccess()){
System.out.println("调用电脑支付成功");
return response.getBody();
}else {
System.out.println("调用电脑支付失败");
}
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//异步通知
public String ali_notify(HttpServletRequest request){
try{Map<String, String> params = new HashMap<>();
Map requestParams = request.getParameterMap();
for (Object o : requestParams.keySet()) {
String name = (String) o;
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCertCheckV1(params, ali_cert_path, charset,sign_type);
if(!signVerified) {
System.out.println("校验失败");
return "fail";
}
String trade_status = params.get("trade_status");
String order_ids = URLDecoder.decode(params.get("passback_params"), "UTF-8"); //传过来的业务参数
if (trade_status.equals("TRADE_SUCCESS")){
System.out.println("支付成功:"+trade_status);
//业务逻辑...
return "success";
}
}catch (Exception e){
e.printStackTrace();
}
return "fail";
}
//退款
public String ali_refund(Order order){
try{CertAlipayRequest certAlipayRequest = new CertAlipayRequest();
certAlipayRequest.setServerUrl(gaturl);
certAlipayRequest.setAppId(appid);
certAlipayRequest.setPrivateKey(app_private_key);
certAlipayRequest.setFormat("json");
certAlipayRequest.setCharset(charset);
certAlipayRequest.setSignType(sign_type);
certAlipayRequest.setCertPath(app_cert_path);
certAlipayRequest.setAlipayPublicCertPath(ali_cert_path);
certAlipayRequest.setRootCertPath(ali_root_cert_path);
AlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
RefundPar refundPar = new RefundPar();
refundPar.setOut_trade_no(order.getOut_trade_no());
refundPar.setTrade_no(order.getTrade_no());
refundPar.setOut_request_no(order.getOrder_sn());
refundPar.setRefund_amount(order.getPay_amount());
request.setBizContent(GsonUtil.getgson().toJson(refundPar));
AlipayTradeRefundResponse response = alipayClient.certificateExecute(request);
if(response.isSuccess()){
System.out.println("调用退款成功");
//业务逻辑
return response.getBody();
} else {
System.out.println("调用退款失败");
}
}catch (Exception e){
e.printStackTrace();
}
return null;
}
======================================================================================
//支付宝同步跳转接口
@RequestMapping("/ali_return_url")
public String ali_return_url(HttpServletRequest request){
return "<html>\n" +
"<head>\n" +
"</head>\n" +
"<body>\n" +
"<div style=\"display: flex\">\n" +
" <b style=\"margin: 100px auto;color: red;font-size: 50px;\"> 支付成功:"+request.getParameter("total_amount") +"元 </b>\n" +
"</div>\n" +
"</body>\n" +
"</html>";
}
//支付宝基本接口ok.拿去即用
微信
1.搞到微信需要的一些证书文件后,yml配置:
2.再来一个配置类:
3.Controller自己写, Service:
<!--pom.xml文件引入微信sdk-->
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
=============================================================================
@Resource
WxPayAppConfig myWXPayConfig;
//wx支付
public String WeChat(FinalParma finalParma){
Map<String, String> returnMap = new HashMap<>();
Map<String, String> responseMap = new HashMap<>();
Map<String, String> requestMap = new HashMap<>();
try {
WXPay wxpay = new WXPay(myWXPayConfig);
requestMap.put("body", finalParma.getSubject()); // 商品描述
requestMap.put("out_trade_no", "1415659990"); // 商户订单号
requestMap.put("total_fee", "855"); // 总金额
requestMap.put("spbill_create_ip", "123.123.123.123"); // 终端IP
requestMap.put("trade_type", "NATIVE"); // 支付类型
requestMap.put("notify_url", myWXPayConfig.getWx_notify_url()); // 接收微信支付异步通知回调地址
Map<String, String> resultMap = wxpay.unifiedOrder(requestMap);
System.out.println(resultMap);
String returnCode = resultMap.get("return_code");
String returnMsg = resultMap.get("return_msg");
if ("SUCCESS".equals(returnCode)) {
String resultCode = resultMap.get("result_code");
String errCodeDes = resultMap.get("err_code_des");
if ("SUCCESS".equals(resultCode)) {
responseMap = resultMap;
}
}
if (responseMap.isEmpty()) {
System.out.println("结果为空");
return "结果为空";
}
// 3、签名生成算法
Long time = System.currentTimeMillis() / 1000;
String timestamp = time.toString();
returnMap.put("appid", myWXPayConfig.getAppID());
returnMap.put("partnerid", myWXPayConfig.getMchID());
returnMap.put("prepayid", responseMap.get("prepay_id"));
returnMap.put("noncestr", responseMap.get("nonce_str"));
returnMap.put("timestamp", timestamp);
returnMap.put("package", "Sign=WXPay");
returnMap.put("sign", WXPayUtil.generateSignature(returnMap, myWXPayConfig.getKey())); //微信支付签名
System.out.println("调用微信支付成功");
return "ok";
} catch (Exception e) {
e.printStackTrace();
return "微信支付统一下单异常";
}
}
//异步通知
public String wx_notify(String notifyStr) {
String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ";
try {
// 转换成map
Map<String, String> resultMap = WXPayUtil.xmlToMap(notifyStr);
WXPay wxpayApp = new WXPay(myWXPayConfig);
if (wxpayApp.isPayResultNotifySignatureValid(resultMap)) {
String returnCode = resultMap.get("return_code"); //状态
String outTradeNo = resultMap.get("out_trade_no");//商户订单号
String transactionId = resultMap.get("transaction_id");
if (returnCode.equals("SUCCESS")) {
if (StringUtils.isNotBlank(outTradeNo)) {
System.out.println("成功");
xmlBack = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return xmlBack;
}
//退款
public String wx_refund(Order order){
Map<String, String> responseMap = new HashMap<>();
Map<String, String> requestMap = new HashMap<>();
WXPay wxpay = new WXPay(myWXPayConfig);
// requestMap.put("out_trade_no", orderNo);
// requestMap.put("out_refund_no", UUIDGenerator.getOrderNo());
// requestMap.put("total_fee", "订单支付时的总金额,需要从数据库查");
// requestMap.put("refund_fee", String.valueOf((int)(amount*100)));//所需退款金额
// requestMap.put("refund_desc", refundReason);
try {
responseMap = wxpay.refund(requestMap);
} catch (Exception e) {
e.printStackTrace();
}
String return_code = responseMap.get("return_code"); //返回状态码
String return_msg = responseMap.get("return_msg"); //返回信息
if ("SUCCESS".equals(return_code)) {
String result_code = responseMap.get("result_code"); //业务结果
String err_code_des = responseMap.get("err_code_des"); //错误代码描述
if ("SUCCESS".equals(result_code)) {
//表示退款申请接受成功,结果通过退款查询接口查询
return "退款申请成功";
} else {
return "错误";
}
} else {
return "错误";
}
}
=====================================================================================
//微信异步接口
@RequestMapping("/wx_notify_url")
public String wx_notify_url(HttpServletRequest request){
System.out.println("微信异步通知");
InputStream is = null;
String xmlBack = "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[报文为空]]></return_msg></xml> ";
try {
is = request.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
xmlBack = service_weChat.wx_notify(sb.toString());
} catch (Exception e) {
System.out.println("微信手机支付回调通知失败");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return xmlBack;
}
OK
银联
1.打开银联开发平台,找到开发包 下载:
解压找到这几个文件,配置文件就拷贝到项目里,配置一下证书文件的路径就可以:
3.拷贝开发包中的sdk, 把sdk里面的所有类搞到项目里:
4.再把demo文件里面的这个类搞到项目里,改个名,我改成UnionpayBese:
5.再搞一个类:
@Component
public class InitUnionPayProject implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
SDKConfig.getConfig().loadPropertiesFromSrc();
}
}
6.一共有这些东西:
7.Service:
//银联支付
public String UnionPay(FinalParma finalParma,int isMobile){
try
{
Map<String, String> requestData = new HashMap<String, String>();
requestData.put("version", UnionpayBese.version);
requestData.put("encoding", UnionpayBese.encoding); //字符集编码
requestData.put("signMethod", SDKConfig.getConfig().getSignMethod());
requestData.put("txnType", "01"); //交易类型 ,01:消费
requestData.put("txnSubType", "01"); //交易子类型, 01:自助消费
requestData.put("bizType", "000201"); //业务类型,B2C网关支付,手机wap支付
requestData.put("frontUrl", frontUrl); //前台跳转地址
requestData.put("backUrl", natapp + backUrl); //异步通知地址
requestData.put("merId", merID);
requestData.put("accessType", "0");
System.out.println("订单号:" +finalParma.getOut_trade_no());
requestData.put("orderId", finalParma.getOut_trade_no());
requestData.put("txnTime", TimeUtils.getDate("yyyyMMddHHmmss"));
requestData.put("currencyCode", "156");
requestData.put("txnAmt", changeBranch(finalParma.getTotal_amount()));
if(isMobile==1){
System.out.println("手机网页");
requestData.put("channelType", "08");
}else{
System.out.println("pc网页");
requestData.put("channelType", "07");
}
requestData.put("reqReserved", finalParma.getPassback_params()); //穿透域,传业务参数
requestData.put("riskRateInfo", "{commodityName="+finalParma.getSubject()+"}");
Map<String, String> submitFromData = AcpService.sign(requestData, UnionpayBese.encoding);
String requestFrontUrl = SDKConfig.getConfig().getFrontRequestUrl();
String html = AcpService.createAutoFormHtml(requestFrontUrl, submitFromData, UnionpayBese.encoding);
return html;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//元转分
String changeBranch(String amount) {
String currency = amount.replaceAll("\\$|\\¥|\\,", "");
int index = currency.indexOf(".");
int length = currency.length();
Long amLong;
if (index == -1) {
amLong = Long.valueOf(currency + "00");
} else if (length - index >= 3) {
amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
} else if (length - index == 2) {
amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
} else {
amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
}
return amLong.toString();
}
//银联异步通知
public boolean unionpay_notify(HttpServletRequest request){
try{
String encoding = request.getParameter(SDKConstants.param_encoding);
Map<String, String> reqParam = new HashMap<String, String>();
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
reqParam.put(en, value);
if (reqParam.get(en) == null || "".equals(reqParam.get(en))) {
reqParam.remove(en);
}
}
}
Map<String, String> valideData = null;
if (null != reqParam && !reqParam.isEmpty()) {
Iterator<Map.Entry<String, String>> it = reqParam.entrySet().iterator();
valideData = new HashMap<String, String>(reqParam.size());
while (it.hasNext()) {
Map.Entry<String, String> e = it.next();
String key = (String) e.getKey();
String value = (String) e.getValue();
valideData.put(key, value);
}
}
if (!AcpService.validate(valideData, encoding)) {
System.out.println("验签失败,需解决验签问题!");
} else {
String order_ids = valideData.get("reqReserved");
String[] idArr = order_ids.split(",");
List<Order> orders = service_order.GetOrder(idArr,"","");
for (Order order: orders){
if(order.getStatus()==0){ //如果没支付,就处理业务逻辑
// order.setOut_trade_no(valideData.get("orderId"));
// order.setTrade_no(valideData.get("queryId")); queryId这个比较重要
}
}
return true;
}
}catch (Exception e){
e.printStackTrace();
return false;
}
return false;
}
//银联退款
public String unionpay_refund(Order order){
Map<String, String> data = new HashMap<String, String>();
data.put("version", UnionpayBese.version);
data.put("encoding", UnionpayBese.encoding); //字符集编码 可以使用UTF-8,GBK两种方式
data.put("signMethod", SDKConfig.getConfig().getSignMethod()); //签名方法
data.put("txnType", "04"); //交易类型 04-退货
data.put("txnSubType", "00"); //交易子类型 默认00
data.put("bizType", "000301"); //业务类型 B2C网关支付,手机wap支付
data.put("channelType", "07"); //渠道类型,07-PC,08-手机
data.put("merId", merID);
data.put("accessType", "0");
data.put("orderId", "T"+order.getOut_trade_no()); //不能一样哦
data.put("txnTime", TimeUtils.getDate("yyyyMMddHHmmss"));
data.put("currencyCode", "156");
data.put("txnAmt", changeBranch(order.getPay_amount().toString()));
data.put("backUrl", "http://www.specialUrl.com"); //不需要通知
data.put("origQryId", order.getTrade_no());
Map<String, String> reqData = AcpService.sign(data,UnionpayBese.encoding);
Map<String, String> rspData = AcpService.post(reqData,SDKConfig.getConfig().getBackRequestUrl(),UnionpayBese.encoding);
try{
System.out.println("rspData: "+ rspData);
if (AcpService.validate(rspData, UnionpayBese.encoding)) {
String respCode = rspData.get("respCode");
if ("00".equals(respCode)) {
//.....
return "退款成功";
}
}
}catch (Exception e){
e.printStackTrace();
return null;
}
return null;
// 分转元:
String y = request.getParameter("txnAmt");
BigDecimal.valueOf(Long.valueOf(y)).divide(new BigDecimal(100)).toString();
三个支付基本集成了, 测试可以正式就改改就可以,银联的最麻烦
银联有个坑,异步通知会发长报文过来,要停止异步通知只能回应200,但会先回应100,导致无限异步通知, 没想到解决方法
VUE
打开后台传的html文本就可以支付了
借鉴了一些文章,感谢各位前辈