ssm 微信扫码支付
来源:互联网 发布:c 程序员招聘 编辑:程序博客网 时间:2024/06/06 06:29
导入JAR包
12345
// https://mvnrepository.com/artifact/com.google.zxing/javasecompile group: 'com.google.zxing', name: 'javase', version: '3.1.0'// https://mvnrepository.com/artifact/com.github.wxpay/wxpay-sdkcompile group: 'com.github.wxpay', name: 'wxpay-sdk', version: '0.0.3'
建立常量配置
12345678910111213141516171819202122232425262728293031323334353637383940
package com.shop.constant;/*** @author 阳十三* @email wdful165177@gmail.com* @blog http://www.item1024.com* @date 2017/9/12* 支付常量*/public class PayConstant {//支付方式/**** 微信支付*/public final static int WEPAY=1;// 微信支付/**** 支付宝支付*/public final static int ALPAY=2;/*** 银联支付*/public final static int unionpay=3;//微信商户相关资料public final static String APP_ID = " ";public final static String APP_SECRET = " ";public final static String MCH_ID = " ";public final static String API_KEY = " ";//微信接口资料public final static String NOTIFY_URL = " "; //支付结果异步回调地址public final static String TRADE_TYPE = "NATIVE";//选择NAVITE那么上传的ip就可以是发机支付的本机ippublic final static String API_URL = " ";public final static String CREATE_IP="127.0.0.1"; //本季ippublic final static String UFDODER_URL="https://api.mch.weixin.qq.com/pay/unifiedorder"; //微信下单接口public final static String QUERY_URL="https://api.mch.weixin.qq.com/pay/orderquery"; //微信查询接口public final static String REFUND_URL="https://api.mch.weixin.qq.com/secapi/pay/refund"; //申请退款的接口}
支付配置文件
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
package com.shop.constant;import com.github.wxpay.sdk.WXPayConfig;import java.io.ByteArrayInputStream;import java.io.File;import java.io.FileInputStream;import java.io.InputStream;import static com.shop.constant.PayConstant.API_KEY;import static com.shop.constant.PayConstant.APP_ID;import static com.shop.constant.PayConstant.MCH_ID;/*** @author 阳十三* @email wdful165177@gmail.com* @blog http://www.item1024.com* @date 2017/9/13*/public class WxPayConfig implements WXPayConfig {private byte[] certData;//初始化退款、撤销时的商户证书public WxPayConfig() throws Exception {String certPath = "/Users/mac/IdeaProjects/GShop/src/main/resources/pay/cert/apiclient_cert.p12";File file = new File(certPath);InputStream certStream = new FileInputStream(file);this.certData = new byte[(int) file.length()];certStream.read(this.certData);certStream.close();}public String getAppID() {return APP_ID;}/** 微信支付商户号 */public String getMchID() {return MCH_ID;}public String getKey() {return API_KEY;}public int getHttpConnectTimeoutMs() {return 8000;}public int getHttpReadTimeoutMs() {return 10000;}@Overridepublic InputStream getCertStream() {ByteArrayInputStream certBis;certBis = new ByteArrayInputStream(this.certData);return certBis;}}
编写service
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
package com.shop.service;import com.shop.annotation.DataSource;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Transactional;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Map;/*** @author 阳十三* @email wdful165177@gmail.com* @blog http://www.item1024.com* @date 2017/9/12*/@Transactional(rollbackFor=Exception.class,isolation = Isolation.REPEATABLE_READ)public interface WxPayService {/*** 下单接口* @param out_trade_no 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。* @param total_fee 订单总金额,单位为分,只能为整数* @param userId 用户id* @param productId 商品id* @return 二维码短链接*/@DataSource("write")String wxPayByQrcode(String out_trade_no,String total_fee,String productId,int userId) throws Exception;/**** @param out_trade_no 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。* @param total_fee 订单总金额,单位为分,只能为整数* @param out_refund_no 商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。* @param refund_fee 退款总金额,订单总金额,单位为分,只能为整数* @return String*/@DataSource("write")String wxPayRefund(String out_trade_no,String total_fee,String out_refund_no,String refund_fee) throws Exception;/*** 支付回调接口* @param request* @param response*/@DataSource("write")void wxPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception;/*** 订单查询接口*/Map<String,String> wxPayQuery(String out_trade_no) throws Exception;}
编写实现类 impl
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
package com.shop.service.Impl;import com.github.wxpay.sdk.WXPay;import com.github.wxpay.sdk.WXPayUtil;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatWriter;import com.google.zxing.common.BitMatrix;import com.shop.constant.WxPayConfig;import com.shop.mapper.*;import com.shop.pojo.IntegralLog;import com.shop.pojo.Orders;import com.shop.pojo.SystemOption;import com.shop.pojo.UserPayList;import com.shop.service.UserPayListService;import com.shop.service.WxPayService;import com.shop.utils.WxPayUtils;import com.shop.utils.XmlUtils;import org.jdom2.JDOMException;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Repository;import org.springframework.stereotype.Service;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.util.*;import java.util.concurrent.TimeUnit;import static com.shop.constant.PayConstant.*;/*** @author 阳十三* @email wdful165177@gmail.com* @blog http://www.item1024.com* @date 2017/9/12*/@Servicepublic class WxPayServiceImpl implements WxPayService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Resourceprivate UserPayListMapper userPayListMapper;private WxPayConfig wxPayConfig;private WXPay wxPay;@Resourceprivate OrdersMapper ordersMapper;@Resourceprivate UserInfoMapper userInfoMapper;@Resourceprivate SystemOptionMapper systemOptionMapper;@Resourceprivate IntegralLogMapper integralLogMapper;/*** @param out_trade_no 商户订单号* @param total_fee 标价金额* @param userId 用户id* @param productId 商品id* @return 微信支付所需的二维码生成的 短链接*/@Overridepublic String wxPayByQrcode(String out_trade_no, String total_fee, String productId, int userId) throws Exception {System.out.println("Wxpay start");//防止请求二维码的时候订单号会重复if (redisTemplate.hasKey(out_trade_no)) {System.out.println("Wxpay二维码存在 返回缓存的二维码");return redisTemplate.opsForValue().get(out_trade_no);}UserPayList userPayList = new UserPayList();userPayList.setOrderId((out_trade_no));userPayList.setPayAmount(Double.valueOf(total_fee) / 100);userPayList.setPayType(WEPAY);userPayList.setPayCreatetime(new java.sql.Date(System.currentTimeMillis()));userPayList.setUserId(userId);userPayList.setpStatus(0);String code_url = "订单重复了";wxPayConfig = new WxPayConfig();wxPay = new WXPay(wxPayConfig);String currTime = WxPayUtils.getCurrTime();String strTime = currTime.substring(8, currTime.length());String strRandom = WxPayUtils.buildRandom(4) + "";String nonce_str = strTime + strRandom;//设置请求参数Map<String, String> data = new HashMap<String, String>();data.put("body", "奥农汇");data.put("out_trade_no", out_trade_no);data.put("nonce_str", nonce_str);data.put("fee_type", "CNY");data.put("total_fee", total_fee);data.put("spbill_create_ip", CREATE_IP);data.put("notify_url", NOTIFY_URL);data.put("trade_type", TRADE_TYPE); // 此处指定为扫码支付data.put("product_id", productId);try {//发起支付Map<String, String> resp = wxPay.unifiedOrder(data);System.out.println(resp);if (resp.get("result_code").equals("SUCCESS")) {//获取二维码URLcode_url = resp.get("code_url");userPayListMapper.insertSelective(userPayList);//存入redis 防止二次请求重复redisTemplate.opsForValue().set(out_trade_no, code_url);//设置半个小时二维码过期redisTemplate.expire(out_trade_no, 15, TimeUnit.MINUTES);}} catch (Exception e) {e.printStackTrace();}return code_url;}@Overridepublic String wxPayRefund(String out_trade_no, String total_fee, String out_refund_no, String refund_fee) throws Exception {//设置请求参数String flag = "FAIL";HashMap<String, String> data = new HashMap<String, String>();wxPayConfig = new WxPayConfig();wxPay = new WXPay(wxPayConfig);data.put("out_trade_no", out_trade_no);data.put("out_refund_no", out_refund_no);data.put("total_fee", total_fee);data.put("refund_fee", refund_fee);data.put("refund_fee_type", "CNY");try {//调用sdk发起退款Map<String, String> result = wxPay.refund(data);System.out.println(result);if ("SUCCESS".equals(result.get("result_code"))) {//TODO:更新订单System.out.println("订单" + result.get("out_trade_no") + "微信退款成功");try {ordersMapper.updateStaByOrderIdAndSta(result.get("out_trade_no"), 8, 6);flag = "SUCCESS";} catch (Exception e) {e.getStackTrace();}}} catch (Exception e) {e.printStackTrace();}return flag;}@Overridepublic void wxPayNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {// 读取回调内容InputStream inputStream;StringBuffer sb = new StringBuffer();inputStream = request.getInputStream();String s;BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));while ((s = in.readLine()) != null) {sb.append(s);}in.close();inputStream.close();// 支付结果通知的xml格式数据String notifyData = sb.toString();// 转换成mapMap<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);//支付确认内容String resXml = "";wxPayConfig = new WxPayConfig();wxPay = new WXPay(wxPayConfig);//验证签名if (wxPay.isPayResultNotifySignatureValid(notifyMap)) { // 签名正确if (notifyMap.get("out_trade_no") != null) {if ("SUCCESS".equals(notifyMap.get("result_code"))) { //交易成功// TODO:更新订单System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付成功");try {//更改订单状态ordersMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), 1, 2);//更改支付记录表状态userPayListMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), 0, 1);//增加用户积分int userid = userPayListMapper.selectUserIdByOrderId(notifyMap.get("out_trade_no"));//获取积分规则SystemOption systemOption = systemOptionMapper.selectByPrimaryKey(1);Double amount = Double.parseDouble(notifyMap.get("total_fee")) / 100 / systemOption.getIntegralMinusrule();userInfoMapper.updateAmountByUserIdInc(amount, userid);//积分日志IntegralLog integralLog = new IntegralLog();integralLog.setIntegralChangenum(amount);integralLog.setIntegralChangereason("购买商品");integralLog.setIntegralChangetime(new Date(System.currentTimeMillis()));integralLog.setIntegralChangetype(1);integralLog.setIntegralRestnum(0.00);integralLogMapper.insertSelective(integralLog);//设置成功确认内容resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} catch (Exception e) {System.out.println("更改订单状态异常");e.getStackTrace();}} else { //交易失败try {ordersMapper.updateStaByOrderIdAndSta(notifyMap.get("out_trade_no"), null, 7);} catch (Exception e) {e.getStackTrace();}resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg></return_msg>" + "</xml> ";System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付失败");}}// 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功} else { // 签名错误,如果数据里没有sign字段,也认为是签名错误//设置失败确认内容resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg></return_msg>" + "</xml> ";System.out.println("订单" + notifyMap.get("out_trade_no") + "微信支付失败");}//发送通知response.getWriter().println(resXml);}/**** @param out_trade_no 订单号* @return* @throws Exception*/@Overridepublic Map<String, String> wxPayQuery(String out_trade_no) throws Exception {HashMap<String, String> data = new HashMap<String, String>();Map<String, String> result = new HashMap<>();wxPayConfig = new WxPayConfig();wxPay = new WXPay(wxPayConfig);data.put("out_trade_no", out_trade_no);try {//调用sdk发起退款result = wxPay.orderQuery(data);}catch (Exception e){e.getStackTrace();}return result;}}
控制器编写
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
package com.shop.controller;import com.google.zxing.BarcodeFormat;import com.google.zxing.EncodeHintType;import com.google.zxing.MultiFormatWriter;import com.google.zxing.client.j2se.MatrixToImageWriter;import com.google.zxing.common.BitMatrix;import com.shop.service.WxPayService;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.OutputStream;import java.util.HashMap;import java.util.Map;/*** @author 阳十三* @email wdful165177@gmail.com* @blog http://www.item1024.com* @date 2017/9/12* 系统支付控制器*/@Controller@RequestMapping(value = "/Pay")public class PayController {@Resourceprivate WxPayService wxPayService;@RequestMapping("/wxPayByQrcode.py")@ResponseBodypublic void orderPay(HttpServletRequest request, HttpServletResponse response) throws Exception {String code_url = wxPayService.wxPayByQrcode("20150806125377", "1", "18", 59);System.out.println(code_url);//根据url生成二维码MultiFormatWriter multiFormatWriter = new MultiFormatWriter();// 设置二维码参数Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");BitMatrix bitMatrix = multiFormatWriter.encode(code_url, BarcodeFormat.QR_CODE, 300, 300, hints);//返回二维码MatrixToImageWriter.writeToStream(bitMatrix, "jpg", response.getOutputStream());}@RequestMapping("wxPayNotify")@ResponseBodypublic void wxPayNotify(HttpServletRequest request,HttpServletResponse response) throws Exception {wxPayService.wxPayNotify(request,response);}}
下单 退款测试
123456
@Testpublic void wxPayRund() throws Exception {String str = wxPayService.wxPayRefund("20150806125377","1","","1");System.out.println(str);}
阅读全文
0 0
- ssm 微信扫码支付
- java在SSM下使用支付宝扫码支付
- 支付宝电脑支付,微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付
- 微信扫码支付-原生支付-流程图
- 微信扫码支付-Native原生支付
- 支付篇—微信扫码支付
- ssm
- SSM
- MySQL中删除重复数据只保留一条
- noSQL DB 技术选型
- java的final变量浅析
- YAML 语言教程
- (CodeForces
- ssm 微信扫码支付
- SpringBoot系列
- Java面试宝典
- 机器学习xgboost实战—手写数字识别 (DMatrix)
- Java初学者问题图解_动力节点Java学院整理
- SpringMVC异常处理
- 【Java】try-catch-finally语句中return的执行顺序思考
- 新版支付宝支付
- 腾讯前端一面