最近搞了个团油的项目,还是一个星期就干出来的项目,其中的事情就不多说了,过来人都知道。在这里介绍一下微信的APP支付吧
首先第一步,从网上找到微信的开发文档,看看你是哪种支付,是哪种支付就点哪种支付。我是APP支付就演示这个了。
到了这里 我建议开发者先去把业务流程仔细看一遍,知道我们后台要干啥,前台要干啥。(其实方便甩锅)
这里我就不再上业务流程的图了,直接说
API
我没有做退款功能,只有支付功能,但是后台其实只用到了统一下单这个接口,让我们看一下需要哪些必填参数
微信后台可以直接给我们的有3个必填的参数,也是最重要的3个参数
应用id(APP_ID),商户号(MCH_ID),应用对应的秘钥(APP_KEY)
这3个参数可以从微信的商户平台取,我自己没有就不演示了
在这里上代码
我的配置类,涉及隐私的地方,我用*代替
package com.thundersdata.backend.basic.configure;
import com.github.wxpay.sdk.WXPayConfig;
import org.apache.poi.util.IOUtils;
import java.io.InputStream;
/**
* @Author: wrc
* @Classname MyWxpayConfig
* @Description TODO
* @Date 2020/5/28 13:38
* @Created wrc
*/
public class MyWxpayConfig implements WXPayConfig {
private byte [] certData;
public MyWxpayConfig() throws Exception{
InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cert/apiclient_cert.p12");
this.certData = IOUtils.toByteArray(certStream);
certStream.close();
}
/**
* 微信开发平台应用ID, 从微信商户取
*/
public static final String APP_ID = "****";
/**
* 应用对应的凭证
*/
// public static final String APP_SECRET = "";
/**
* 应用对应的密钥, 从微信商户取
*/
public static final String APP_KEY = "****";
/**
* 微信支付商户号, 从微信商户取
*/
public static final String MCH_ID = "*****";
/**
* 商品描述
*/
public static final String BODY = "付款";
/**
* 商户号对应的密钥
*/
// public static final String PARTNER_key = "";
/**
* 商户id 非必填
*/
public static final String PARTNER_ID = "*******";
/**
* 常量固定值
*/
public static final String GRANT_TYPE = "client_credential";
/**
* 获取预支付id的接口url 写死的地址
*/
public static String GATEURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
/**
* 微信服务器回调通知url 自己的回调接口,一定要是是域名访问才行,建议搞个nginx反向代理一下,在nginx上配置一下可以获取真实的IP地址
*/
public static String NOTIFY_URL = "https://****.com/Pay/wx_back"; //可以访问的url
/**
* 微信服务器查询订单url 写死的地址
*/
public static String ORDER_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery";
@Override
public String getAppID() {
return APP_ID;
}
@Override
public String getMchID() {
return MCH_ID;
}
@Override
public String getKey() {
return APP_KEY;
}
@Override
public InputStream getCertStream() {
return null;
}
@Override
public int getHttpConnectTimeoutMs() {
return 8000;
}
@Override
public int getHttpReadTimeoutMs() {
return 10000;
}
}
接口类
OllOrder是我自己封装的订单类,里面有我想要的具体参数,比如金额,下单用户id…
package com.thundersdata.backend.basic.controller;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.thundersdata.backend.basic.configure.MyWxpayConfig;
import com.thundersdata.backend.basic.model.OllOrder;
import com.thundersdata.backend.basic.service.WxPayService;
import com.thundersdata.backend.basic.utils.AESUtil2;
import com.thundersdata.backend.basic.utils.HttpResult;
import com.thundersdata.backend.basic.utils.IPUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @Author: wrc
* @Classname PayController
* @Description TODO
* @Date 2020/5/28 14:34
* @Created wrc
*/
@Api(tags = "支付")
@RestController
@RequestMapping("/Pay")
public class PayController {
@Autowired
private WxPayService wxPayService;
private Logger logger = LoggerFactory.getLogger(PayController.class);
@ApiOperation(value = "微信支付")
@PostMapping("/wxOrder")
public HttpResult orderPay(@RequestBody @Valid OllOrder data, HttpServletRequest request) throws Exception {
try {
System.err.println("进入微信支付申请");
System.out.println(data);
String spbill_create_ip = IPUtils.getIpAddr(request);
String key = MyWxpayConfig.APP_KEY;
System.err.println(spbill_create_ip);
Map<String, String> resultMap = wxPayService.dounifiedOrder(data, spbill_create_ip);
HttpResult result=HttpResult.ok("订单生成");
result.setData(resultMap);
return result; //给前端app返回此字符串,再调用前端的微信sdk引起微信支付
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
return HttpResult.error("服务器繁忙,请稍后");
}
}
/**
* 微信订单回执信息接口
* @param request
* @return
* @throws Exception
*/
@ApiOperation(value = "微信订单回执信息接口")
@PostMapping("wx_back")
public String test(HttpServletRequest request) throws Exception {
String result=null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
System.out.println("==="+sb.toString());
result=wxPayService.payBack(sb.toString());
} catch (Exception e) {
e.printStackTrace();
logger.error("服务器繁忙,请稍后");
} finally {
return result;
}
}
}
Service类
package com.thundersdata.backend.basic.service;
import com.alibaba.fastjson.JSONObject;
import com.thundersdata.backend.basic.model.OllOrder;
import java.util.Map;
/**
* @Author: wrc
* @Classname WxPayService
* @Description TODO
* @Date 2020/5/28 14:36
* @Created wrc
*/
public interface WxPayService {
Map<String, String> dounifiedOrder(OllOrder ollOrder, String spbill_create_ip) throws Exception;
String payBack(String notifyData) throws Exception;
}
ServiceImpl类
package com.thundersdata.backend.basic.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.thundersdata.backend.basic.configure.MyWxpayConfig;
import com.thundersdata.backend.basic.model.OllOrder;
import com.thundersdata.backend.basic.service.OllOrderService;
import com.thundersdata.backend.basic.service.WxPayService;
import com.thundersdata.backend.basic.vo.OllOrderOne;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @Author: wrc
* @Classname WxPayServiceImpl
* @Description TODO
* @Date 2020/5/28 14:36
* @Created wrc
*/
@Service
public class WxPayServiceImpl implements WxPayService {
private static Logger logger = LoggerFactory.getLogger(WxPayServiceImpl.class);
@Autowired
OllOrderService OllOrderService;
@Override
public Map<String, String> dounifiedOrder(OllOrder ollOrder, String spbill_create_ip) throws Exception {
//用户id
String userId = String.valueOf(ollOrder.getCreateUserId());
//金额
String amount = ollOrder.getActualAmount();
Map<String, String> fail = new HashMap<>();
MyWxpayConfig config = new MyWxpayConfig();
WXPay wxpay = new WXPay(config);
Map<String, String> data = new HashMap<String, String>();
//应用ID
data.put("appid", MyWxpayConfig.APP_ID);
//商户号
data.put("mch_id", MyWxpayConfig.MCH_ID);
//随机字符串
data.put("nonce_str", WXPayUtil.generateNonceStr());
// data.put("nonce_str", "test");
//根据订单的种类不同充值类型不同
String body="全民乐享-加油";
data.put("body", body);
//商户订单号
String outTradeNo= UUID.randomUUID().toString().replaceAll("-", "");
ollOrder.setNumber(outTradeNo);
data.put("out_trade_no", outTradeNo);
System.out.println("====="+amount);
String total = String.format("%.0f", Double.valueOf(amount) * 100);
//总金额
data.put("total_fee", total);
//终端IP
data.put("spbill_create_ip", spbill_create_ip);
//异步通知地址(请注意必须是外网)
data.put("notify_url", MyWxpayConfig.NOTIFY_URL);
// data.put("openid",openId);
//交易类型
data.put("trade_type", "APP");
// data.put("attach", attach);
// data.put("sign", MD5Util.getSign(data));
//应用对应的密钥
String sign11 = WXPayUtil.generateSignature(data, MyWxpayConfig.APP_KEY);
System.out.println("sign:" + sign11);
//签名
data.put("sign", WXPayUtil.generateSignature(data, MyWxpayConfig.APP_KEY));
System.out.println(data);
StringBuffer url = new StringBuffer();
Map<String,String>dataMap=new HashMap<String,String>();
Map<String,String> map = new HashMap<>();
try {
//下单
Map<String, String> resp = wxpay.unifiedOrder(data);
if("SUCCESS".equals(resp.get("result_code"))){
String nonce_str = (String)resp.get("nonce_str");
//预支付交易会话标识
String prepay_id = (String)resp.get("prepay_id");
Long time =System.currentTimeMillis()/1000;
//吊起支付接口
map.put("appid",config.getAppID());
map.put("partnerid",config.getMchID());
map.put("package","Sign=WXPay");
map.put("noncestr",nonce_str);
map.put("timestamp",time+"");
map.put("prepayid",prepay_id);
String sign=WXPayUtil.generateSignature(map, MyWxpayConfig.APP_KEY);
map.put("sign",sign);
System.out.println(resp);
//map.put("time",System.currentTimeMillis()/1000+"");
ollOrder.setStatus(0);
OllOrderService.insertSelective( ollOrder);
}
resp.put("time",System.currentTimeMillis()/1000+"");
return map;
} catch (Exception e) {
System.out.println(e.getMessage());
logger.info(e.getMessage());
}
return fail;
}
/**
* 回调
* @param notifyData
* @return
* @throws Exception
*/
@Override
@Transactional(rollbackFor = RuntimeException.class)
public String payBack(String notifyData) throws Exception {
Map<String,String> notifyMap=WXPayUtil.xmlToMap(notifyData);
MyWxpayConfig config = new MyWxpayConfig();
WXPay wxpay = new WXPay(config);
Map<String,String> resultMap=new HashMap<String,String>();
resultMap.put("return_code","SUCCESS");
resultMap.put("return_msg","OK");
//验证
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
//签名正确
//状态码SUCCESS或者FALL
System.out.println(1);
String result_code=notifyMap.get("result_code").toUpperCase();
//订单号
String out_trade_no = notifyMap.get("out_trade_no");
OllOrder order = OllOrderService.selectOne(out_trade_no);
System.out.println(order);
OllOrder ordered = new OllOrder();
if("SUCCESS".equals(result_code)) {
System.out.println(2);
System.out.println(notifyMap);
//总金额,微信返回的金额是分为单位的,转化为元为单位的
Double total_fee = Double.valueOf(notifyMap.get("total_fee")) / 100;
System.out.println(String.format("%.0f", total_fee));
if(order.getStatus()==0){
//所有验证结束后 进行订单状态的修改
System.out.println("修改订单状态");
order.setStatus(1);
OllOrderService.updateByPrimaryKeySelective(order);
ordered.setId(order.getId());
ordered.setStatus(1);
ordered.setUpdateTime(new Date());
System.out.println("支付===="+ordered);
OllOrderService.updateByPrimaryKeySelective(ordered);
}
}else {
//微信返回支付失败信息修改支付状态为失败
//String out_trade_no=notifyMap.get("out_trade_no");
ordered.setId(order.getId());
//状态码4为支付失败
order.setStatus(4);
OllOrderService.updateByPrimaryKeySelective(order);
ordered.setStatus(4);
ordered.setUpdateTime(new Date());
System.out.println("支付===="+ordered);
OllOrderService.updateByPrimaryKeySelective(ordered);
}
}else {
System.out.println("签名错误");
logger.info("签名错误");
new RuntimeException("签名错误");
}
notifyMap.remove("sign");
String sign11 = WXPayUtil.generateSignature(notifyMap, MyWxpayConfig.APP_KEY);
System.out.println("=========|||"+sign11);
return WXPayUtil.mapToXml(resultMap);
}
}
版权声明:本文为weixin_50185313原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。