微信支付-JAVA

小编在此说一声,建议去看一下微信官方提供的支付流程图,以及其他的之后再看下面的。小编在此就不提供账号申请,那些准备工作了,直接上代码。

微信官方流程→点击打开

流程总结:首先APP发送一个请求,想购买的商品。后台生成一个预支付订单,然后将APP支付所需要的信息返回给App支付即可。支付成功后,微信服务器回调你请求预支付订单告诉微信服务器的回调地址。收到回调后执行你的业务逻辑。并在最后一定要告诉微信服务器你已收到回调,不然微信会无限回调你。

以下有几个注意事项:

  1、建议订单金额不在交互中直接暴露传输,防止篡改。

  2、一般流程是在请求预支付的订单的时候在自己数据库中设计两张表,一张是支付订单表,一张是订单流水表。支付订单表设计一个状态,未支付,已支付。在预支付订单中可传输自己的订单号out_trade_no,通过这个标识。收到该订单的标识就将状态改成已支付,且在流水表中记录充值金额之类的信息。

 3、在回调中需要订单是否已被处理过,再判断实际支付金额和订单金额是否匹配。防止实际支付金额被篡改。

 4、微信的单位是分哦,所以记得处理一下。

好的现在我们就直接上代码:

controller

package com.irandoo.support.wxpay.action;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import java.text.ParseException;


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.jdom2.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.alibaba.fastjson.JSON;
import com.irandoo.app.interf.json.PrivateRoomJson;
import com.irandoo.app.interf.service.PrivateRoomJsonService;
import com.irandoo.support.wxpay.handler.PrepayIdRequestHandler;
import com.irandoo.support.wxpay.model.RechargeOrder;
import com.irandoo.support.wxpay.service.RechargeOrderService;

import com.irandoo.support.wxpay.util.ConstantUtil;
import com.irandoo.support.wxpay.util.MD5Util;
import com.irandoo.support.wxpay.util.OrderUtil;
import com.irandoo.support.wxpay.util.WXUtil;
import com.irandoo.support.wxpay.util.XMLUtil;
import com.irandoo.xhep.base.action.BaseAction;
import com.irandoo.xhep.base.model.Meal;
import com.irandoo.xhep.base.service.MealService;
import com.irandoo.xhep.base.service.RechargeRecordService;
import com.irandoo.xhep.base.service.UserAccountService;
import com.irandoo.xhep.base.util.WawaConstantUtil;

/**
*<p>Title:WeiXinPayController </p>
*<p>Description:</p>
*<p>Company:</p> 
*@author sun
*@date 2018年1月22日10:01:19
*/
@Controller("wechatPayAction")
@Scope("prototype")
public class WechatPayAction extends BaseAction {

	/**
	 * 
	 */
	private static final long serialVersionUID = 4071603624936342541L;
	
	private Log logger = LogFactory.getLog(WechatPayAction.class);
	@Autowired
	MealService mealService;
	@Autowired
	RechargeOrderService rechargeOrderService;
	@Autowired
	UserAccountService userAccountService;
	@Autowired
	RechargeRecordService rechargeRecordService;
	@Autowired
    PrivateRoomJsonService privateRoomJsonService; 
	/**
     * 生成预支付订单,获取prepayId
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
	public String wxPay(){

	    String o = request.getParameter("object");
		Map<String,Object> paramMap = (Map<String,Object>)JSON.parse(o);
		//----------------------获取App传过来的参数-------------------
		//获取套餐id
		String meals = (String) paramMap.get("mealId");	

		Long mealId = Long.parseLong(meals);

		//获取套餐详细信息
	    Meal meal =	mealService.getInfoByMealId(mealId);
	    //获取用户id
	    String userId = (String) request.getAttribute("userId");

	    logger.info("套餐价格:"+meal.getPrice());
		//获取充值渠道
		String channelName = (String) paramMap.get("channelName");
		//房间id
		String roomId = (String) paramMap.get("roomId");
		String privateRoomId = null;
		String receiveUserId = null;
		RechargeOrder rechargeOrder =new RechargeOrder();
        if (null != paramMap.get("roomId")){//它充
        	//获取房间id
   	        roomId = (String) paramMap.get("roomId");	
   	        rechargeOrder.setRoomId(Long.parseLong(roomId));
   	       if (null != paramMap.get("privateRoomId")) {
 	        //获取包房id
 	        privateRoomId = (String) paramMap.get("privateRoomId");
 	        //根据包房id获取被充人
 	        Map<String, Object> mealmap = new HashMap<>();
 	        mealmap.put("id", privateRoomId);
 	        List<PrivateRoomJson> m =  privateRoomJsonService.returnInfo(mealmap);
 	        //获取被充人id
 			 receiveUserId = m.get(0).getCreator();;
 			 rechargeOrder.setReceiveUserId(Long.parseLong(receiveUserId));
 	         rechargeOrder.setPrivateRoomId(Long.parseLong(privateRoomId));
 		    }   
		 }else{//自充
			 receiveUserId = userId;
			 rechargeOrder.setReceiveUserId(Long.parseLong(receiveUserId));
		 }
		
		Map<String, Object> map=new HashMap<String, Object>();
		//2.5 订单号,此处用时间加随机数生成,商户根据自己情况调整,只要保持全局唯一就行  
        String strReq =OrderUtil.createOrderId();
        //设置充值订单实体
       
        rechargeOrder.setOrderId(strReq);
        rechargeOrder.setBuyUserId(Long.parseLong(userId));
        rechargeOrder.setMealId(mealId);
        rechargeOrder.setPayMoney(meal.getPrice());
        rechargeOrder.setPayType(channelName); 
        //生成交易订单
        try {
        	 rechargeOrderService.insert(rechargeOrder);
        	 logger.info("成功交易单成功!");
		} catch (Exception e) {
			e.printStackTrace();
			logger.info("生成交易单失败!");
		}
        //获取充值金额;
        String total_fee= meal.getPrice()*100+"";             //充值金额
		String out_trade_no=strReq;                      //订单号
		String timestamp = WXUtil.getTimeStamp();        //超时时间
		String nonce_str = WXUtil.getNonceStr();         // 生成随机字符串
		//---------------------------------------------- ***** 统一下单开始 *****  -----------------------------------------------------------
		 //3.获取生成预支付订单的请求类
        PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);     
        prepayReqHandler.setParameter("appid",  ConstantUtil.APP_ID);                  //平台应用appId
        prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID);                  //商户号
        prepayReqHandler.setParameter("nonce_str", nonce_str);                         //随机字符串
        prepayReqHandler.setParameter("body",   ConstantUtil.BUY_BODY);                //商品描述
        prepayReqHandler.setParameter("out_trade_no", out_trade_no);                   //订单号
        prepayReqHandler.setParameter("total_fee",String.valueOf(total_fee));          //订单价格
        prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr());    //获取客户端ip
        prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL);          //回调通知
        prepayReqHandler.setParameter("trade_type", "APP");                            //支付类型
        prepayReqHandler.setParameter("time_start", timestamp);                        //时间戳
        prepayReqHandler.setGateUrl(ConstantUtil.GATEURL);                             //设置预支付id的接口url
        //3.3 注意签名(sign)的生成方式,具体见官方文档(传参都要参与生成签名,且参数名按照字典序排序,最后接上APP_KEY,转化成大写)
        prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());    //sign 签名
        //3.4 提交预支付,获取prepayid 
        String prepayid = null;
		try {
			prepayid = prepayReqHandler.sendPrepay();
			logger.debug("预支付订单id----:"+prepayid);
		
		} catch (Exception e) {
			e.printStackTrace();
		}
		//---------------------------------------------- ***** 统一下单 结束 *****  --------------------------------------------------------------
	    //3.5 若获取prepayid成功,将相关信息返回客户端
		String result = null;
		String errmsg = null;
	   if (prepayid != null && !prepayid.equals("")) {
		   String signs = 
                   "appid=" + ConstantUtil.APP_ID +
                   "&noncestr=" + nonce_str + 
                   "&package=Sign=WXPay"+ 
                   "&partnerid="+ ConstantUtil.PARTNER_ID + 
                   "&prepayid=" + prepayid + 
                   "×tamp=" + timestamp+
                   "&key="+ ConstantUtil.APP_KEY;  
		   map.put("appid", ConstantUtil.APP_ID);
		   map.put("partnerid", ConstantUtil.PARTNER_ID);     //商家id
		   map.put("prepayid", prepayid);                     //预支付id
		   map.put("package", "Sign=WXPay");                  //固定常量
		   map.put("noncestr", nonce_str);                    //与请求prepayId时值一致
		   map.put("timestamp", timestamp);                   //等于请求prepayId时的time_start
		   map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());//签名方式与上面类似
		   result = "0";
		   errmsg = "";
		  } else {
		    result = "-1";
			errmsg = "获取prepayid失败";
			logger.info("获取prepayid失败");
		  }
        return returnJson(map, result, errmsg);
	}

    /**
     * 9.2 接收微信支付成功通知
     * @param request
     * @param response
     * @throws IOException
     * @throws java.io.IOException 
     * @throws ParseException 
    */
    public void getnotify()throws IOException, ParseException {
         //1.创建输入输出流
         PrintWriter writer = response.getWriter();
         InputStream inStream = request.getInputStream();
         ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            //2.将结果转换
            String result = new String(outSteam.toByteArray(), "utf-8");
            logger.info("微信支付通知结果:" + result);
            Map<String, String> map = null;
            try {
                //3.解析微信通知返回的信息
                map = XMLUtil.doXMLParse(result);
                logger.info("微信返回结果:" + map);
            } catch (JDOMException e) {
                e.printStackTrace();
            }
            // 4.若支付成功,则告知微信服务器收到通知
            if (map != null && map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
	            String out_trade_no = map.get("out_trade_no");
	            String wechatMoney = map.get("total_fee");
	            rechargeOrderService.unifiedOrder(WawaConstantUtil.SYS_PAY_WECHAT, out_trade_no, wechatMoney);
            	}
            String notifyStr = XMLUtil.setXML("ERROR", "");
            writer.write(notifyStr);
            writer.flush();
    }  
}

 

serviceImpl   (因为牵扯到支付宝支付,所以回调中将两个整合到一起了)

 

	@Override
	public boolean unifiedOrder(String pay_type,String out_trade_no,String money) {
		  log.info("------支付成功-----");
	      boolean flag = true;
           try {
        	   //查询订单实体
               RechargeOrder rechargeOrder = rechargeOrderMapper.getInfoByOrderId(out_trade_no);
         
               if("2".equals(rechargeOrder.getState())||2==rechargeOrder.getState()){
              	 log.info("....已经回调成功过了.....");
               } else if(rechargeOrder.getState().equals("1")||rechargeOrder.getState()==1){  
              	 //判断实付金额与订单金额是否一致
              	 String payMoney = money;
              	 log.info("订单金额 :"+rechargeOrder.getPayMoney());
              	 String orderPayMoney = null;
	              	 if(WawaConstantUtil.SYS_PAY_WECHAT.equalsIgnoreCase(pay_type)){ //微信支付
	              		orderPayMoney = rechargeOrder.getPayMoney()*100+"";
	              	 } else { //否则支付宝支付
	              		orderPayMoney = rechargeOrder.getPayMoney()+"";
	              	 }
	              	 log.info("orderPayMoney"+orderPayMoney+"----payMoney"+payMoney);
              	 if(orderPayMoney.equals(payMoney)){
              		 //修改订单状态
		                  rechargeOrder.setState(Long.parseLong("2"));	
		                int n = rechargeOrderMapper.updateState(rechargeOrder);
			               if(n>0){//修改成功,执行添加账户的操作
			            	//获取充值人的id
			            	Long receiveUserId = rechargeOrder.getReceiveUserId();
			            	//根据套餐id获取套餐信息
			            	Meal meal= mealMapper.getInfoByMealId(rechargeOrder.getMealId());
		            	       //获取套餐里的币
			                Long doll_coin = meal.getDoll_coin();
			                //获取套餐奖励的币
			                Long reward_coin = meal.getReward_coin();
			                //判断是否是首充
			               int sumCount = 0; 
			               UserGameConnectionJson userGameConnectionJson =  userGameConnectionJsonMapper.getInfoById(rechargeOrder.getBuyUserId());
			               //添加首充系统消息
		                	SysInformation sysInformation = new SysInformation();
			               if("1".equals(userGameConnectionJson.getIsFirstPay())){
			                	sumCount=(int) (doll_coin+reward_coin);
			                	sysInformation.setUser_id(receiveUserId);
			                	sysInformation.setContent("恭喜您充值成功,获得"+sumCount+"个币。");
			                	sysInformation.setType(WawaConstantUtil.SYS_PAY);
			                }else{
			                	sumCount=(int) (doll_coin+reward_coin+meal.getFirst_reward_coin());				                	
			                	sysInformation.setUser_id(receiveUserId);
			                	Long sum = doll_coin+reward_coin;
			                	sysInformation.setContent("恭喜您首充次充值成功,获得"+sum+"个币。奖励您"+meal.getFirst_reward_coin()+"个币。");
			                	sysInformation.setType(WawaConstantUtil.SYS_FIRSTPAY);
			                	//修改首充状态
			                	userGameConnectionJson.setIsFirstPay("1");
			                }
			               /**执行会员升级**/
			                UpgradeMembershipUtil.member(rechargeOrder.getBuyUserId()+"", rechargeOrder.getPayMoney()+"");
			               //添加累计充值金额
		                	userGameConnectionJson.setSumPayMoney(userGameConnectionJson.getSumPayMoney()+meal.getPrice());
				           	//修改用户关联
			                userGameConnectionJsonMapper.update(userGameConnectionJson);
			                sysInformationMapper.insert(sysInformation);
			                 //执行添加币的服务
			                Map<String, Object> accountMap =new HashMap<String, Object>();
			                  accountMap.put("userId", receiveUserId);
			                  //默认充值币账户
			                  accountMap.put("accountType", 1);
			                  accountMap.put("balance", sumCount);
			                int m = userAccountMapper.addBalance(accountMap);
			                //----执行每日任务----
			            	Map<String,Object> map = new HashMap<String,Object>();
			        		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
			        		String date = sdf.format(new Date());
			        		log.info("当前日期:"+date);
			        		map.put("userId", receiveUserId);
			        		map.put("statisticsDate",date);
			        		map.put("taskDate",date);
			                DayTaskThread.startDayTask(InterfaceConstantUtil.PAY, map);
			                if(m>0){//添加成功
			                	//添加充值流水
			                	RechargeRecord  rechargeRecord = new RechargeRecord();
			                	if(null!=rechargeOrder.getRoomId()){
			                		rechargeRecord.setRoom_id(rechargeOrder.getRoomId());
			                	}		               
			                	rechargeRecord.setUser_id(rechargeOrder.getBuyUserId());
		                        rechargeRecord.setMeal_id(rechargeOrder.getMealId());
		                        rechargeRecord.setRecharge_order_id(out_trade_no);
		                        rechargeRecord.setRecharge_user_id(rechargeOrder.getReceiveUserId());
		                        rechargeRecord.setOrder_money(meal.getPrice());
		                        rechargeRecord.setExchange_coin(new Integer(meal.getDoll_coin()+""));
		                        rechargeRecord.setReward_coin(new Integer(meal.getReward_coin()+""));
		                        rechargeRecord.setPay_type(rechargeOrder.getPayType());
		                        rechargeRecord.setPay_money(rechargeOrder.getPayMoney());
		                        rechargeRecord.setType(1); //默认充值充值流水为充值                	
		                        rechargeRecordMapper.insert(rechargeRecord);
			                }else{
			                	 log.info(out_trade_no+"------充值账户失败-----");
			                }
	              	 }else{
	              		 //修改订单状态(失败)
		                 rechargeOrder.setState(Long.parseLong("0"));	
		                 rechargeOrderMapper.updateState(rechargeOrder);
		            	 log.info("------修改订单状态失败-----");
	              	 }
              	
	            }else{
	            	 log.info("非法回调,订单金额与回调金额不一致.");
	              }
             }else{
              	log.info("失败订单");   
             }
		  } catch (Exception e) {
			   flag=false;
			e.printStackTrace();
		  }
               return flag;
	 }

   最后提示:将里面的业务逻辑改成你自己的业务逻辑就好了。 

  工具类下载地址---点击到达→

 小编在此就不细细说明了,有什么问题注释应该都写了,还有要问题的,可以联系QQ985548426.小编长期在线。

  配上源码下载地址:https://download.csdn.net/download/a985548426/10752519

 

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值