【SpringBoot2微信支付实例】

编程

1、 POM添加微信开发支持

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.5.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<dependency>

<groupId>com.github.wxpay</groupId>

<artifactId>wxpay-sdk</artifactId>

<version>0.0.3</version>

</dependency>

2、yml配置

weixin:

#正式环境

wxpay:

useSandbox: true

app_id: adfasfasdfsdf //公众账号ID

mch_id: 134dddddd4901// 商户号

key: 13579246800987654321abcdefssssghijkl// 商户密钥

certPath: src/weixin/apiclient_cert.p12//从微信商户平台下载的安全证书存放的路径

spbill_create_ip: 114.55.200.128 //APP和网页支付提交用户端ip, Native支付填调用微信支付API的机器IP, 即:服务器ip地址

notify_url: // 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。(需要配置)

trade_type: NATIVE

placeanorder_url: https://api.mch.weixin.qq.com/pay/unifiedorder

return_url_html: // 微信支付 - 统一下单地址

sandboxSignKeyurl: https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey

attach: 教育

3、wechatConfig配置文件获取yml配置

@Data

@Configuration

public class WeChatConfig {

@Value("${weixin.wxpay.useSandbox}")

private boolean useSandbox;//是否沙箱环境

@Value("${weixin.wxpay.app_id}")

public String app_id; // 公众账号ID

@Value("${weixin.wxpay.mch_id}")

public String mch_id ; // 商户号

@Value("${weixin.wxpay.key}")

public String key; // 商户密钥

@Value("${weixin.wxpay.certPath}")

public String certPath =

ClassUtils.getDefaultClassLoader().getResource("").getPath()+"/weixin/apiclient_cert.p12";

//从微信商户平台下载的安全证书存放的路径

// APP和网页支付提交用户端ip, Native支付填调用微信支付API的机器IP, 即:服务器ip地址

@Value("${weixin.wxpay.spbill_create_ip}")

public String spbill_create_ip;

// 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。(需要配置)

@Value("${weixin.wxpay.notify_url}")

public String notify_url;

// 支付方式,取值如下:JSAPI,NATIVE,APP

@Value("${weixin.wxpay.trade_type}")

public String trade_type;

@Value("${weixin.wxpay.placeanorder_url}")

// 微信支付 - 统一下单地址

public String placeanorder_url;

@Value("${weixin.wxpay.attach}")

public String attach;

}

4、支付代码处理文件

controller层

/**

* 正式使用环境

* @param id

* @param req

* @param response

* @return

* @throws Exception

*/

@RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})

public BaseResponse orderPay(@RequestParam Integer id,@RequestParam(required = false) Integer acuId,

HttpServletRequest req, HttpServletResponse response) throws Exception {

log.info("进入微信支付申请");

DlOrder dlOrder = idlOrderService.get(id);

String out_trade_no=dlOrder.getOdUuid(); // 需要前端给的参数

//获取金额,根据业务逻辑获取

String total_fee = idlOrderService.useOrNotCoupon(dlOrder,acuId); //微信支付钱的单位为分

log.info("支付金额:",total_fee);

//String user_id= dlOrder.getCreateUser(); //

String attach=weChatConfig.getAttach();

String spbill_create_ip= weChatConfig.getSpbill_create_ip();//IP地址

log.info(spbill_create_ip);

//生成订单

Map<String,String> result = wxOrderService.dounifiedOrder(id,attach,out_trade_no,total_fee,spbill_create_ip,1);

if (null != result)

{

String code_url = result.get("code_url");

log.info("返回图片地址:{}",code_url);

BufferedImage image = PayUtil.getQRCodeImge(code_url);

response.setContentType("image/jpeg");

response.setHeader("Pragma","no-cache");

response.setHeader("Cache-Control","no-cache");

response.setIntHeader("Expires",-1);

ImageIO.write(image, "JPEG", response.getOutputStream());

return successToJson(result,"获取微信支付订单成功");

}else {

return fail("获取微信支付订单失败");

}

//return resultString; //给前端app返回此字符串,再调用前端的微信sdk引起微信支付

}

service层:

//生成订单

@Override

public Map<String, String> dounifiedOrder(Integer id,String attach, String out_trade_no,

String total_fee, String spbill_create_ip, int type) throws Exception {

//第一步、查询微信服务器是否有订单

//第二步、有,则关闭先前的订单

//第三步、生成新订单

WXPay wxpay = new WXPay(config, WXPayConstants.SignType.HMACSHA256,false);

//微信生成订单参数

Map<String, String> data = convertToWXData(attach,out_trade_no,total_fee,spbill_create_ip,type);

StringBuffer url= new StringBuffer();

Map<String,String> existsresp = getExistOrder(wxpay,out_trade_no);

String existsresp_return_code = existsresp.get("return_code");

String existsresp_trade_state= existsresp.get("trade_state");

String existsresp_result_code= existsresp.get("result_code");

log.info("查询订单:{}",JSON.toJSONString(existsresp));

log.info("更新前out_trade_no:{}",out_trade_no);

if ("SUCCESS".equals(existsresp_return_code))

{

log.info("关闭已有订单,订单existsresp_return_code:{},existsresp_result_code:{},existsresp_trade_state:{}",

existsresp_return_code,existsresp_result_code,existsresp_trade_state);

if ("SUCCESS".equals(existsresp_result_code)

&& ("NOTPAY".equals(existsresp_trade_state)||"CLOSED".equals(existsresp_trade_state)))

{

log.info("关闭已有订单,订单existsresp_result_code:{}",existsresp_result_code);

closeOrder(wxpay,out_trade_no);

//更改订单UUID

out_trade_no = StringUtil.getOrderID();

data.put("out_trade_no",out_trade_no);

DlOrder dlOrder = new DlOrder();

dlOrder.setId(id);

dlOrder.setOdUuid(out_trade_no);

int i = dlOrderMapper.updateByID(dlOrder);

log.info("更新后out_trade_no:{}",out_trade_no);

}

}

try {

Map<String, String> resp = wxpay.unifiedOrder(data);

String returnCode = resp.get("return_code"); //获取返回码

String returnMsg = resp.get("return_msg");

//String nonce_str = resp.get("nonce_str");//微信返回的随机字符串

log.info("生成订单的结果:{}",JSON.toJSONString(resp));

if("SUCCESS".equals(returnCode)){ //若返回码为SUCCESS,则会返回一个result_code,再对该result_code进行判断

String resultCode = resp.get("result_code");

String errCodeDes = resp.get("err_code_des");

log.info(resultCode);

if("SUCCESS".equals(resultCode)){

//获取预支付交易回话标志

return convertToWXRst(resp,data);

}else {

//订单已经生成的情况下,直接查询订单返回

Map<String,String> existsresp2 = getExistOrder(wxpay,out_trade_no);

log.info("已经存在的订单1:{}",JSON.toJSONString(existsresp2));

log.info("订单号:{},错误信息:{}",out_trade_no,errCodeDes);

return convertToWXRst(existsresp2,data);

}

}else {

//订单已经生成的情况下,直接查询订单返回

Map<String,String> existsresp2 = getExistOrder(wxpay,out_trade_no);

log.info("已经存在的订单2:{}",JSON.toJSONString(existsresp2));

log.info("订单号:{},错误信息:{}",out_trade_no,returnMsg);

}

} catch (Exception e) {

log.info(e.getMessage());

}

return null;

}

/**

* 微信生成订单参数

* @param attach

* @param out_trade_no

* @param total_fee

* @param spbill_create_ip

* @param type

* @return

* @throws Exception

*/

private Map<String, String> convertToWXData(String attach, String out_trade_no,

String total_fee, String spbill_create_ip, int type) throws Exception {

Map<String, String> data = new HashMap<String, String>();

String body="订单支付";

data.put("appid",weChatConfig.getApp_id());

data.put("mch_id",weChatConfig.getMch_id());

data.put("nonce_str",WXPayUtil.generateNonceStr());

data.put("body", body);

data.put("out_trade_no", out_trade_no);

data.put("total_fee", total_fee);

data.put("spbill_create_ip",spbill_create_ip);

//异步通知地址(请注意必须是外网)

data.put("notify_url", weChatConfig.getNotify_url());

data.put("trade_type", weChatConfig.getTrade_type());

data.put("attach", attach);

String signtmp = WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.HMACSHA256);

data.put("sign", signtmp);

log.info("微信环境类型:{}",config.isUseSandbox());

return data;

}

/**

* 查询已有订单

* @param wxpay

* @param out_trade_no

* @return

* @throws Exception

*/

@Override

public Map<String,String> getExistOrder(WXPay wxpay, String out_trade_no) throws Exception {

Map<String,String> data = new HashMap<>();

data.put("out_trade_no",out_trade_no);

data.put("mch_id",weChatConfig.getMch_id());

Map<String, String> existsresp = wxpay.orderQuery(data);

log.info("查看是否有存在的订单:{}",JSON.toJSONString(existsresp));

return existsresp;

}

/**

* 获取订单返回值

* @param resp

* @param data

* @return

* @throws Exception

*/

private Map<String,String> convertToWXRst(Map<String, String> resp,Map<String, String> data) throws Exception {

Map<String,String> map = new HashMap<>();

String prepay_id = resp.get("prepay_id");

map.put("appid",weChatConfig.getApp_id());

map.put("mch_id",weChatConfig.getMch_id());

map.put("prepayid",prepay_id);

map.put("package","Sign=WXPay");

map.put("noncestr",resp.get("nonce_str"));

map.put("timestamp",String.valueOf(System.currentTimeMillis()/1000));

String sign = WXPayUtil.generateSignature(data, config.getKey(), WXPayConstants.SignType.HMACSHA256);

map.put("sign",sign);

map.put("timestamp",resp.get("timestamp"));

map.put("package","WXPay");

map.put("code_url",resp.get("code_url"));

map.put("return_code",resp.get("return_code"));

map.put("result_code",resp.get("result_code"));

if (null != resp.get("trade_state") && "SUCCESS".equals(resp.get("trade_state"))) {

//对于已经支付成功的订单,直接修改订单的状态

//需要判断是否已经支付,只有未支付才需要修改

String out_trade_no = resp.get("out_trade_no");

DlOrder order = dlOrderMapper.getOrderByUUID(out_trade_no);

if(null !=order.getOdStatusCode()

&& "O2".equals(order.getOdStatusCode())) {

DlOrder dlOrder = new DlOrder();

dlOrder.setOdUuid(resp.get("out_trade_no"));

dlOrder.setOdStatusCode("O3");

dlOrder.setOdStatusName("已支付");

dlOrder.setModifyTime(new Date());

dlOrder.setModifyUser("admin@qq.com");

BigDecimal total_fee = new BigDecimal(resp.get("total_fee"));

dlOrder.setOdOutOfPocket(total_fee.multiply(new BigDecimal("100")));

int update = dlOrderMapper.update(dlOrder);

//插入一条支付成功的记录

this.insertPaymentLog(resp,out_trade_no,resp.get("nonce_str"));

}

}

return map;

}

 5、微信服务同步通知页面

/**

* 订单支付异步通知

*/

@ApiOperation(value = "手机订单支付完成后回调")

@RequestMapping(value = "/notify",method = {RequestMethod.GET, RequestMethod.POST})

public String WXPayBack(HttpServletRequest request,HttpServletResponse response){

String resXml="";

log.info("======================>>>微信支付回调<<======================");

try{

//

InputStream is = request.getInputStream();

//将InputStream转换成String

BufferedReader reader = new BufferedReader(new InputStreamReader(is));

StringBuilder sb = new StringBuilder();

String line = null;

try {

while ((line = reader.readLine()) != null) {

sb.append(line + "

");

}

} catch (IOException e) {

e.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

resXml=sb.toString();

//实例测试代码

/* resXml = "<xml><appid><![CDATA[wx7a5088333e7a7234]]></appid>

" +

"<attach><![CDATA[82569575@qq.com,7]]></attach>

" +

"<bank_type><![CDATA[CFT]]></bank_type>

" +

"<cash_fee><![CDATA[1]]></cash_fee>

" +

"<fee_type><![CDATA[CNY]]></fee_type>

" +

"<is_subscribe><![CDATA[N]]></is_subscribe>

" +

"<mch_id><![CDATA[1348674901]]></mch_id>

" +

"<nonce_str><![CDATA[51eec4509f68473da0a660baabaab8a9]]></nonce_str>

" +

"<openid><![CDATA[owyu2v00-fp62nZa-fRvEl2doR1w]]></openid>

" +

"<out_trade_no><![CDATA[2019081211264961401245689]]></out_trade_no>

" +

"<result_code><![CDATA[SUCCESS]]></result_code>

" +

"<return_code><![CDATA[SUCCESS]]></return_code>

" +

"<sign><![CDATA[BDA7CBAA80954C531F5E100559A34992]]></sign>

" +

"<time_end><![CDATA[20190813100643]]></time_end>

" +

"<total_fee>1</total_fee>

" +

"<trade_type><![CDATA[NATIVE]]></trade_type>

" +

"<transaction_id><![CDATA[4200000398201908134997424507]]></transaction_id>

" +

"</xml>";*/

//log.info("回调返回的xml结果值:{}",resXml);

String out_trade_no = wxOrderService.payBack(resXml);

if (null != out_trade_no) {

Thread t = new Thread(new Runnable() {

@Override

public void run() {

//发送邮件

log.info("启动一个线程,微信发送下单邮件。线程编号:{}",Thread.currentThread().getName());

sendPlaceOrderMail(out_trade_no);

}

});

t.start();

}

log.info("支付成功,回调结果:{}",out_trade_no);

return toPaySuccess(out_trade_no);

//return result;

}catch (Exception e){

log.error("手机支付回调通知失败",e);

String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";

return result;

}

}

/***

* 查看支付状态

* @param id

* @param req

* @param response

* @return

*/

@ApiOperation(value = "微信手机订单支付状态")

@RequestMapping(value = "/getWXPayStatus",method = {RequestMethod.GET, RequestMethod.POST})

public BaseResponse getWXPayStatus(@RequestParam Integer id,

HttpServletRequest req, HttpServletResponse response){

try {

DlOrder dlOrder = idlOrderService.get(id);

Map<String, String> wxPayStatus = wxOrderService.getWXPayStatus(dlOrder.getOdUuid());

if (null != wxPayStatus)

{

/*{"transaction_id":"4200000376201908143196470846","nonce_str":"GNAGvXoqGWHocktm","trade_state":"SUCCESS",

"bank_type":"CFT","openid":"owyu2v00-fp62nZa-fRvEl2doR1w",

"sign":"06334CB9CFB0C65C5D09488AEA20A0E32BB323A3D095FAD46EAC843AD430C6B8",

"return_msg":"OK","fee_type":"CNY","mch_id":"1348674901",

"cash_fee":"1","out_trade_no":"2019081411420931412345679",

"appid":"wx7a5088333e7a7234","total_fee":"1",

"trade_state_desc":"支付成功","trade_type":"NATIVE","result_code":"SUCCESS",

"attach":"点教点育","time_end":"20190814114313","is_subscribe":"N","return_code":"SUCCESS"}*/

if ("SUCCESS".equals(wxPayStatus.get("return_code"))

&&"SUCCESS".equals(wxPayStatus.get("result_code"))

&&"SUCCESS".equals(wxPayStatus.get("trade_state")))

{

return successToJson("支付成功");

}

}

} catch (Exception e) {

log.info("---------------获取微信支付状态失败------------------");

e.printStackTrace();

}

return fail("支付中");

}

/**

* 成功业务处理

* @param out_trade_no 订单ID,本地业务订

* @return

*/

private String toPaySuccess(String out_trade_no){

String return_url_html = alipayConfig.getReturn_url_html();

//前后分离形式 直接返回页面 记得加上注解@Response http://login.calidray.com你要返回的网址,再页面初始化时候让前端调用你其他接口,返回信息

StringBuilder sbd = new StringBuilder();

sbd.append("<form action="");

sbd.append(return_url_html);

sbd.append("#/payForSuccess?odUuid=");

sbd.append(out_trade_no);

sbd.append("" method="get" name="form1">

");

sbd.append("</form>

");

sbd.append("<script>document.forms[0].submit();</script>");

// 如果使用优惠券,更新优惠券已经使用

DlOrder order = idlOrderService.getByUUID(out_trade_no);

dlActiveCouponUserService.setAcuIsUsed(order);

log.info("跳转页面:{}",sbd.toString());

return sbd.toString();

}

集成成功,请测试!

以上是 【SpringBoot2微信支付实例】 的全部内容, 来源链接: utcz.com/z/513991.html

回到顶部