关于微信支付和支付宝支付java实现

简介: 目前支付宝支付和微信支付是算是目前app的标配了支付宝支付在更新过后有了官方专门的sdk和demo,所以相对而言比较简单,而微信支付稍微复杂一点,下面的文章会附实例代码,微信支付也是参考的github上的某位大神级人物的代码。

目前支付宝支付和微信支付是算是目前app的标配了

支付宝支付在更新过后有了官方专门的sdk和demo,所以相对而言比较简单,而微信支付稍微复杂一点,下面的文章会附实例代码,微信支付也是参考的github上的某位大神级人物的代码。

首先是微信支付

先准备各种数据,我一般都是放到配置类中,当然也可以放到数据库或者配置文件中

`public final class WxpayConfig  {

       /**

        *商家可以考虑读取配置文件

        */

       //微信开发平台应用id

       public static final String APP_ID = "wx8888888888888888";

       //财付通商户号

       public static final String PARTNER = "1900000109";//app请求的商户号

       public static final String MCHID = "1900000109";//预支付请求的商户号                

       //商户号对应的密钥

       public static final String PARTNER_KEY = "";

       //预支付接口

       public static final String PREPAY_URL =  "https://api.mch.weixin.qq.com/pay/unifiedorder"; 

       //查询订单接口

       public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

       //签名算法常量值

       public static final String SIGN_METHOD = "sha1";

       //异步通知地址

       public static final String NOTIFY_URL = “”;

       //交易类型

       public static final String TRADE_TYPE = "APP";

       //暂定包值

       public static final String PACKAGE = "Sign=WXPay";

       //返回状态成功

       public static final String SUCCESS = "SUCCESS";

       //返回状态失败

       public static final String FAIL = "FAIL";

}`

这是关于微信支付的封装的工具类,其中httpclient和md5加密的需要自己去封装工具类

`public class  WxpayUtil {

       /**

        *随机串

        * @return

        */

       public static String getNonceStr() {

              Random random = new Random();

              return  MD5Util.getMD5String(String.valueOf(random.nextInt(10000)));

       }

       /**

        *时间戳

        * @return

        */

       public static String getTimeStamp() {

              return  String.valueOf(System.currentTimeMillis() / 1000);

       }

       /**

        *解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。

        * @param strxml

        * @return

        * @throws JDOMException

        * @throws IOException

        */

       @SuppressWarnings("unchecked")

       public static Map  parseToMap(String strXml) throws JDOMException, IOException {

              strXml =  strXml.replaceFirst("encoding=\".*\"",  "encoding=\"UTF-8\"");

              if(null == strXml ||  "".equals(strXml)) {

                     return null;

              }

              Map m = new  HashMap<>();


              InputStream in = new  ByteArrayInputStream(strXml.getBytes("UTF-8"));

              SAXBuilder builder = new  SAXBuilder();

              Document doc =  builder.build(in);

              Element root =  doc.getRootElement();

              List list =  root.getChildren();

              Iterator it =  list.iterator();

              while(it.hasNext()) {

                     Element e = it.next();

                     String k = e.getName();

                     String v = "";

                     List  children = e.getChildren();

                     if(children.isEmpty()) {

                            v =  e.getTextNormalize();

                     } else {

                            v =  getChildrenText(children);

                     }

                     m.put(k, v);

              }

              //关闭流

              in.close();

              return m;

       }


       /**

        *获取子结点的xml

        * @param children

        * @return String

        */

       @SuppressWarnings("unchecked")

       private static String  getChildrenText(List children) {

              StringBuffer sb = new  StringBuffer();

              if(!children.isEmpty()) {

                     Iterator  it = children.iterator();

                     while(it.hasNext()) {

                            Element e =  it.next();

                            String name =  e.getName();

                            String value =  e.getTextNormalize();

                            List  list = e.getChildren();

                            sb.append("<"  + name + ">");

                            if(!list.isEmpty())  {

                                   sb.append(getChildrenText(list));

                            }

                            sb.append(value);

                            sb.append("");

                     }

              }

              return sb.toString();

       }

       /**

        *只支持String,并且value非空

        * @param map

        * @return

        */

       public static String  parseToXml(Map map){

              StringBuffer sb = new  StringBuffer("");

              for(Map.Entry entry : map.entrySet()){

                     sb.append("<"+entry.getKey()+">");

                     sb.append("");

                     sb.append("");

              }

              sb.append("");

              return sb.toString();

       }


       /**

     * POST提交XML对象

     * @param document

     */ 


    public static String postXmlClient(String  url,String xmlParams) throws Exception { 


//         return  HttpUtils.postXmlEntity(url, xmlParams).getContent();

     return  HttpClient.postRequest(url, xmlParams);

    } 

}


这是关于微信支付一些参数处理的方法

public class  WxpayHelper {

        /**

     *除去数组中的空值和签名参数

     * @param sArray签名参数组

     * @return去掉空值与签名参数后的新签名参数组

     */

    public static Map  paraFilter(Map sArray) {

        Map result =  new HashMap();

        if (sArray == null || sArray.size()  <= 0) {

            return result;

        }

        for (String key : sArray.keySet()) {

            String value = sArray.get(key);

            if (value == null ||  value.equals("") || key.equalsIgnoreCase("sign") ||  key.equalsIgnoreCase("key")) {

                continue;

            }

            result.put(key, value);

        }

        return result;

    }


    /**

     *把数组所有元素,并按照“参数=参数值”的模式用“&”字符拼接成字符串

     * @param params需要参与字符拼接的参数组

     * @param sorts   是否需要排序 true 或者false

     * @return拼接后字符串

     */

    public static String  createLinkString(Map params) {

        List keys = new  ArrayList(params.keySet());

        Collections.sort(keys);

        String prestr = "";

        for (int i = 0; i < keys.size();  i++) {

            String key = keys.get(i);

            String value = params.get(key);

            if (i == keys.size() - 1) {//拼接时,不包括最后一个&字符

                prestr = prestr + key +  "=" + value;

            } else {

                prestr = prestr + key +  "=" + value + "&";

            }

        }

        return prestr;

    }


    /**

     *验签响应签名

     * @param paras

     * @return

     */

    public static boolean  verify(Map paras){

     String  sign = paras.get("sign");

     if(StringUtils.isBlank(sign))  return false;

     return  sign.equals(WxpayBuilder.buildRequestMysign(paraFilter(paras)));

    }


    /**

     *响应成功

     * @param loggerAgent -日志代理

     * @return String

     */

    /*public static String yes(ILoggerAgent  loggerAgent){

     Map  return_wx = new HashMap<>();

     return_wx.put("return_code",  WxpayConfig.SUCCESS);

     loggerAgent.payParamsLogger(null  , "WX-NOTIFY", false, return_wx);

     return  WxpayUtil.parseToXml(return_wx);

    }*/

   }


public class  WxpayBuilder {

        /**

     *生成签名结果

     * @param sPara要签名的数组

     * @return签名结果字符串

     */

       public static String  buildRequestMysign(Map sPara) {

     String  prestr =  WxpayHelper.createLinkString(sPara)+"&key="+WxpayConfig.PARTNER_KEY;

     LogFactory.getInstance().getLogger().debug("微信支付签名的字符串:"+prestr);

        return  MD5Util.getMD5String(prestr).toUpperCase();

    }


    public static Map  buildRequestPara(Map sParaTemp) {

        //除去数组中的空值和签名参数

        Map sPara =  WxpayHelper.paraFilter(sParaTemp);

        //生成签名结果

        String mysign =  buildRequestMysign(sPara);


  LogFactory.getInstance().getLogger().debug("微信支付签名数据:"+mysign);

        //签名结果与签名方式加入请求提交参数组中

        sPara.put("sign", mysign);

        return sPara;

    }

}`

使用例程

其中业务接口信息,参考https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3


  `     /**

        *微信订单逻辑

        *

        * @throws Exception

        */

       public 

  Map wxPayLogic() throws Exception {

              //微信业务代码

              Map xmlData  = new HashMap();

              xmlData.put("appid",  WxpayConfig.APP_ID);

              xmlData.put("mch_id",  WxpayConfig.MCHID);

              xmlData.put("nonce_str",  WxpayUtil.getNonceStr());

              xmlData.put("out_trade_no",);

              xmlData.put("total_fee",);

              xmlData.put("spbill_create_ip",“”);

              //从数据字典里面去主机地址

              DataDictionary dataDictionary =  dataDictionaryService.getDicByKey("PAY_CALLBACK");

              xmlData.put("notify_url",  dataDictionary.getValue() + WxpayConfig.NOTIFY_URL);

              xmlData.put("trade_type",  WxpayConfig.TRADE_TYPE);

              xmlData.put("body",  "");

              //少写签名

              Map result  = WxpayBuilder.buildRequestPara(xmlData);

              // Map  result = WxpayHelper.paraFilter(xmlData);

              String xmlParams =  WxpayUtil.parseToXml(result);

              LogFactory.getInstance().getLogger().debug("微信支付请求报文:" + xmlParams);

              String xmlResult =  WxpayUtil.postXmlClient(WxpayConfig.PREPAY_URL, xmlParams);

              Map map =  WxpayUtil.parseToMap(xmlResult);

              LogFactory.getInstance().getLogger().debug("微信支付返回报文:" + JsonHelper.toJson(map));

              //返回时SUCCESS

              if  (WxpayConfig.SUCCESS.equals(map.get("return_code"))) {

                     //验证返回是否成功

                     if  (WxpayConfig.SUCCESS.equals(map.get("result_code"))) {

                            //除去签名和空值

                            Map paraFilter = WxpayHelper.paraFilter(map);

                            //获得签名

                            String mysign =  WxpayBuilder.buildRequestMysign(paraFilter);

                            //验证签名

                            if  (mysign.equals(map.get("sign"))) {

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

                                   //验证签名成功

                    //进行操作

                            } else {

                                   //签名验证失败

                                   LogFactory.getInstance().getLogger().debug("微信支付验证签名失败");

                            }

                     } else {

                            // result_code返回失败

                            String err_code =  map.get("err_code");

                            String  err_code_des = map.get("err_code_des");

                            chargeRecord.setCauses(err_code+err_code_des);

                            LogFactory.getInstance().getLogger().debug("微信支付结果失败:失败码为"+err_code+",失败原因是"+err_code_des);

                            chargeRecord.setState(2);

                     }

              } else {

                     // return_code返回失败

                     String return_msg =  map.get("return_msg");

                     LogFactory.getInstance().getLogger().debug("微信支付返回失败:返回消息为:" + return_msg);

                     return null;

              }

              //微信支付

              Map  mapBack = new HashMap<>();

              mapBack.put("appid",  WxpayConfig.APP_ID);

              mapBack.put("partnerid",  WxpayConfig.PARTNER);

              mapBack.put("prepayid",  chargeRecord.getOpenId());

              mapBack.put("package",  WxpayConfig.PACKAGE);

              mapBack.put("noncestr",  WxpayUtil.getNonceStr());

              mapBack.put("timestamp",  WxpayUtil.getTimeStamp());

              return  WxpayBuilder.buildRequestPara(mapBack);

       }`

支付异步回传

接收到异步通知之后,才算是付款成功

`@Controller

@RequestMapping(value  = "/api")

public class  WxPayCallbackController extends BaseController {


       @Autowired

       OrderLogic orderLogic;

       @Autowired

       RedisFactory redisFactory;

       @Autowired

       ApplicationContext applicationContext;


       @RequestMapping(value =  "/wxPayCallback", method = RequestMethod.POST)

       @ResponseBody

       public String  wxPayCallback(@RequestBody String body) {

              MDC.put("seqID",  SeqIdGenerator.generate());//日志序列

              LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付结果通知信息data=" + body);

              Map  resultMap = new HashMap<>();

              if  (StringUtils.isNotBlank(body)) {

                     try {

                            Map map = WxpayUtil.parseToMap(body);

                            //返回代码

                            if  (WxpayConfig.SUCCESS.equals(map.get("return_code"))) {

                                   //验证签名

                                   if  (WxpayHelper.verify(map)) {

                                          //验证业务结果是否成功

                                          String  outTradeNo = map.get("out_trade_no");

                                          if  (WxpayConfig.SUCCESS.equals(map.get("result_code"))) {

                                                 //设置支付类型,1为支付宝,2为微信

                                                 map.put("payType","2");

                           //通过所有验证,启动事件,通过spring的监听器进行监听,并执行付款成功后的业务

                                                 applicationContext.publishEvent(new  OrderFinishEvent(map));

                                          }  else {

                                                 //业务结果失败

                                                 LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付业务结果失败");

                                                 orderLogic.updateState(outTradeNo,2);

                                                 resultMap.put("return_code",  WxpayConfig.SUCCESS);

                                          }

                                   } else {

                                          //签名失败

                                          LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付签名失败");

                                          resultMap.put("return_code",  WxpayConfig.FAIL);

                                          resultMap.put("return_msg",  "签名失败");

                                   }

                            } else {

                                   //返回结果失败

                                   LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的异步支付返回结果失败");

                                   resultMap.put("return_code",  WxpayConfig.FAIL);

                                   resultMap.put("return_msg",  "参数格式校验错误");

                            }

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              } else {

                     //返回结果为空

                     LogFactory.getInstance().getPayCallbackLogger().info("参数格式校验错误");

                     resultMap.put("return_code",  WxpayConfig.FAIL);

                     resultMap.put("return_msg",  "参数格式校验错误");

              }

              return  WxpayUtil.parseToXml(resultMap);

       }


}`

付款成功统一处理事件监听

`@Component

public class OrderFinishLister {




  @EventListener


  public void onApplicationEvent(OrderFinishEvent event){//这里不能抛出异常,外层无法处理,会造成中断


  try {

            Map params =  (HashMap) event.getSource();

            String payType =  params.get("payType");

            String outTradeNo =  params.get("out_trade_no");

            String trade_no = null;

            String buyerLogonId = null;

            String buyerId = null;

            String transactionId = null;

            UserOrder order = null;



  if("1".equals(payType)){

                //支付宝

                 trade_no =  params.get("trade_no");

                 buyerLogonId =  params.get("buyer_logon_id");

                 buyerId =  params.get("buyer_id");

                 //执行付款成功后的业务逻辑


  LogFactory.getInstance().getLogger().debug("支付宝获取支付更新状态:" + outTradeNo);

            }else  if("2".equals(payType)){

                //微信

                 transactionId =  params.get("transaction_id");

                //执行微信付款成功后的业务逻辑


  LogFactory.getInstance().getLogger().debug("微信获取支付更新状态:" + outTradeNo);

            }


  }catch (Exception e){

            e.printStackTrace();


  }


  }

}`

这就是单独的微信支付业务流程

相关文章
|
3月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
3月前
|
消息中间件 人工智能 Java
抖音微信爆款小游戏大全:免费休闲/竞技/益智/PHP+Java全筏开源开发
本文基于2025年最新行业数据,深入解析抖音/微信爆款小游戏的开发逻辑,重点讲解PHP+Java双引擎架构实战,涵盖技术选型、架构设计、性能优化与开源生态,提供完整开源工具链,助力开发者从理论到落地打造高留存、高并发的小游戏产品。
人工智能 关系型数据库 OLAP
409 0
|
5月前
|
移动开发 小程序 开发工具
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
955 0
揭秘微信/支付宝6大支付方式:从扫码到刷脸,谁在偷偷赚你的手续费?优雅草卓伊凡
|
5月前
|
Java 计算机视觉
微信虚拟视频聊天插件,QQ抖音快手虚拟摄像头工具,替换相机视频流java
实现包含了虚拟摄像头核心功能,可以捕获真实摄像头视频流,处理后输出到虚拟摄像头设备。
|
5月前
|
XML Java Android开发
微信虚拟视频插件安卓,微信虚拟相机替换拍照,java源码分享
完整的相机应用项目包含三个主要文件:主活动实现、布局文件和清单文件。代码实现了相机预览、
|
6月前
|
数据可视化 机器人 Java
聊天软件自动回复脚本,微信抖音快手小红书,消息自动回复工具机器人【java】
包含4个完整模块:主逻辑模块实现核心回复功能,工具模块封装常用函数,UI模块提供可视化控制界面
|
6月前
|
XML Java 数据格式
微信不封号无限加人软件,微信一键自动加人软件,java实现批量化加人
本项目包含手机号生成工具与附近人列表展示功能。手机号工具支持批量生成、格式验证及CSV导出,可自定义前缀生成符合中国规则的随机号码。
|
6月前
|
机器人 Java
微信自动回复机器人插件,自动同意回复消息, 微信群管理机器人,JAVA框架
本项目基于开源微信机器人框架开发,提供自动回复私聊消息、自动同意好友请求及微信群管理功能。核心功能包括:自动回复用户消息、处理好友申请(发送欢迎语并备注新好友)、群聊管理(如欢迎新成员、关键词踢人和群内自动回复)。项目依赖 `weixin-java-mp` 和 `weixin-java-cp` 核心库,并结合 Lombok 和 Guava 提升开发效率。代码结构清晰,包含配置类 `WechatBotConfig` 初始化服务实例,以及多个处理器实现具体逻辑。下载地址:https://www.pan38.com/share.php?code=r4HGg,提取码:8888(仅供学习参考)。