WeChat Pay-JAVA

The editor is here to say, I suggest you take a look at the payment flow chart provided by WeChat official, and then look at the following. The editor will not provide an account application here. Those preparations can be directly added to the code.

WeChat official process → click to open

Process summary: First, the APP sends a request for the product it wants to buy. A prepaid order is generated in the background, and then the information required for APP payment is returned to the APP payment. After the payment is successful, the WeChat server will call back the callback address you told the WeChat server to request the prepayment order. Execute your business logic after receiving the callback. And at the end, be sure to tell the WeChat server that you have received the callback, otherwise WeChat will call you back infinitely.

Here are a few caveats:

  1. It is recommended that the order amount is not directly exposed and transmitted in the interaction to prevent tampering.

  2. The general process is to design two tables in your own database when requesting prepaid orders, one is the payment order table and the other is the order flow table. The payment order table is designed with a status, not paid, paid. In prepaid orders, you can transmit your own order number out_trade_no , through this identification. After receiving the identification of the order, the status will be changed to paid, and information such as the recharge amount will be recorded in the flow meter.

 3. In the callback, it is necessary to check whether the order has been processed, and then judge whether the actual payment amount matches the order amount. Prevent the actual payment amount from being tampered with.

 4. The unit of WeChat is points, so remember to deal with it.

Ok now let's go directly to the code:

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 Jan 22, 2018 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;
	/**
     * Generate a prepaid order and get the 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);
		//----------------------Get the parameters passed by the App-------------------
		//get package id
		String meals = (String) paramMap.get("mealId");	

		Long mealId = Long.parseLong(meals);

		//Get package details
	    Meal meal =	mealService.getInfoByMealId(mealId);
	    //get user id
	    String userId = (String) request.getAttribute("userId");

	    logger.info("Meal price:"+meal.getPrice());
		//Get the recharge channel
		String channelName = (String) paramMap.get("channelName");
		// room id
		String roomId = (String) paramMap.get("roomId");
		String privateRoomId = null;
		String receiveUserId = null;
		RechargeOrder rechargeOrder =new RechargeOrder();
        if (null != paramMap.get("roomId")){//It fills
        	//get the room id
   	        roomId = (String) paramMap.get("roomId");	
   	        rechargeOrder.setRoomId (Long.parseLong (roomId));
   	       if (null != paramMap.get("privateRoomId")) {
 	        //Get the private room id
 	        privateRoomId = (String) paramMap.get("privateRoomId");
 	        //Get the charged person according to the private room id
 	        Map<String, Object> mealmap = new HashMap<>();
 	        mealmap.put("id", privateRoomId);
 	        List<PrivateRoomJson> m =  privateRoomJsonService.returnInfo(mealmap);
 	        //Get the charged 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 Order number, here is generated by time plus random number, merchants can adjust it according to their own situation, as long as it is globally unique  
        String strReq =OrderUtil.createOrderId();
        //Set the recharge order entity
       
        rechargeOrder.setOrderId(strReq);
        rechargeOrder.setBuyUserId(Long.parseLong(userId));
        rechargeOrder.setMealId(mealId);
        rechargeOrder.setPayMoney(meal.getPrice());
        rechargeOrder.setPayType(channelName);
        //generate transaction order
        try {
        	 rechargeOrderService.insert(rechargeOrder);
        	 logger.info("Successful transaction order!");
		} catch (Exception e) {
			e.printStackTrace ();
			logger.info("Failed to generate transaction order!");
		}
        //Get the recharge amount;
        String total_fee= meal.getPrice()*100+""; //recharge amount
		String out_trade_no=strReq; //Order number
		String timestamp = WXUtil.getTimeStamp(); //timeout time
		String nonce_str = WXUtil.getNonceStr(); // Generate random string
		//------------------------------------------------------------ ** *** Unified order start***** ------------------------------------------------ ---------------------
		 //3. Get the request class for generating a prepaid order
        PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, response);     
        prepayReqHandler.setParameter("appid", ConstantUtil.APP_ID); //Platform application appId
        prepayReqHandler.setParameter("mch_id", ConstantUtil.MCH_ID); //Merchant ID
        prepayReqHandler.setParameter("nonce_str", nonce_str); //random string
        prepayReqHandler.setParameter("body", ConstantUtil.BUY_BODY); //Product description
        prepayReqHandler.setParameter("out_trade_no", out_trade_no);                   //订单号
        prepayReqHandler.setParameter("total_fee",String.valueOf(total_fee)); //Order price
        prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr()); //Get client ip
        prepayReqHandler.setParameter("notify_url", ConstantUtil.NOTIFY_URL); //Callback notification
        prepayReqHandler.setParameter("trade_type", "APP"); //Payment type
        prepayReqHandler.setParameter("time_start", timestamp); //timestamp
        prepayReqHandler.setGateUrl(ConstantUtil.GATEURL); //Set the interface url of the prepayment id
        //3.3 Pay attention to the generation method of the signature (sign), see the official document for details (passing parameters must participate in the generation of the signature, and the parameter names are sorted in lexicographical order, and finally connected to APP_KEY, converted to uppercase)
        prepayReqHandler.setParameter("sign", prepayReqHandler.createMD5Sign());    //sign 签名
        //3.4 Submit prepayment and get prepayid
        String prepayid = null;
		try {
			prepayid = prepayReqHandler.sendPrepay();
			logger.debug("Prepay order id----:"+prepayid);
		
		} catch (Exception e) {
			e.printStackTrace ();
		}
		//------------------------------------------------------------ ** *** End of unified order ***** ------------------------------------------------ ------------------------
	    //3.5 If the prepayid is obtained successfully, return the relevant information to the client
		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); //Prepay id
		   map.put("package", "Sign=WXPay"); //fixed constant
		   map.put("noncestr", nonce_str); //The same value as when requesting prepayId
		   map.put("timestamp", timestamp); //equal to time_start when requesting prepayId
		   map.put("sign", MD5Util.MD5Encode(signs, "utf8").toUpperCase());//The signature method is similar to the above
		   result = "0";
		   errmsg = "";
		  } else {
		    result = "-1";
			errmsg = "Failed to get prepayid";
			logger.info("Failed to get prepayid");
		  }
        return returnJson(map, result, errmsg);
	}

    /**
     * 9.2 Receive WeChat payment success notification
     * @param request
     * @param response
     * @throws IOException
     * @throws java.io.IOException
     * @throws ParseException
    */
    public void getnotify()throws IOException, ParseException {
         //1. Create input and output streams
         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. Convert the result
            String result = new String(outSteam.toByteArray(), "utf-8");
            logger.info("WeChat payment notification result: " + result);
            Map<String, String> map = null;
            try {
                //3. Parse the information returned by WeChat notification
                map = XMLUtil.doXMLParse(result);
                logger.info("WeChat returns result: " + map);
            } catch (JDOMException e) {
                e.printStackTrace ();
            }
            // 4. If the payment is successful, notify the WeChat server to receive the notification
            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 (Because it involves Alipay payment, the two are integrated in the callback)

	@Override
	public boolean unifiedOrder(String pay_type,String out_trade_no,String money) {
		  log.info("------Payment successful-----");
	      boolean flag = true;
           try {
        	   //Query order entity
               RechargeOrder rechargeOrder = rechargeOrderMapper.getInfoByOrderId(out_trade_no);
         
               if("2".equals(rechargeOrder.getState())||2==rechargeOrder.getState()){
              	 log.info(".... has been successfully called back...");
               } else if(rechargeOrder.getState().equals("1")||rechargeOrder.getState()==1){  
              	 //Determine whether the actual payment amount is consistent with the order amount
              	 String payMoney = money;
              	 log.info("Order Amount:"+rechargeOrder.getPayMoney());
              	 String orderPayMoney = null;
	              	 if(WawaConstantUtil.SYS_PAY_WECHAT.equalsIgnoreCase(pay_type)){ //WeChat payment
	              		orderPayMoney = rechargeOrder.getPayMoney()*100+"";
	              	 } else { //Otherwise Alipay payment
	              		orderPayMoney = rechargeOrder.getPayMoney()+"";
	              	 }
	              	 log.info("orderPayMoney"+orderPayMoney+"----payMoney"+payMoney);
              	 if(orderPayMoney.equals(payMoney)){
              		 //modify order status
		                  rechargeOrder.setState(Long.parseLong("2"));	
		                int n = rechargeOrderMapper.updateState(rechargeOrder);
			               if(n>0){//The modification is successful, and the operation of adding an account is performed
			            	//Get the id of the recharger
			            	Long receiveUserId = rechargeOrder.getReceiveUserId();
			            	//Get the package information according to the package id
			            	Meal meal= mealMapper.getInfoByMealId(rechargeOrder.getMealId());
		            	       //Get the coins in the package
			                Long doll_coin = meal.getDoll_coin();
			                //Get the coins of the package reward
			                Long reward_coin = meal.getReward_coin();
			                //Determine whether it is the first charge
			               int sumCount = 0;
			               UserGameConnectionJson userGameConnectionJson =  userGameConnectionJsonMapper.getInfoById(rechargeOrder.getBuyUserId());
			               //Add first charge system message
		                	SysInformation sysInformation = new SysInformation();
			               if("1".equals(userGameConnectionJson.getIsFirstPay())){
			                	sumCount=(int) (doll_coin+reward_coin);
			                	sysInformation.setUser_id(receiveUserId);
			                	sysInformation.setContent("Congratulations on your successful recharge, get "+sumCount+" coins.");
			                	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("Congratulations on your successful first recharge, get "+sum+" coins. Reward you with "+meal.getFirst_reward_coin()+" coins.");
			                	sysInformation.setType(WawaConstantUtil.SYS_FIRSTPAY);
			                	//Modify the first charge status
			                	userGameConnectionJson.setIsFirstPay("1");
			                }
			               /**Execute membership upgrade**/
			                UpgradeMembershipUtil.member(rechargeOrder.getBuyUserId()+"", rechargeOrder.getPayMoney()+"");
			               //Add cumulative recharge amount
		                	userGameConnectionJson.setSumPayMoney(userGameConnectionJson.getSumPayMoney()+meal.getPrice());
				           	//modify user association
			                userGameConnectionJsonMapper.update(userGameConnectionJson);
			                sysInformationMapper.insert(sysInformation);
			                 //Execute the service of adding coins
			                Map<String, Object> accountMap =new HashMap<String, Object>();
			                  accountMap.put("userId", receiveUserId);
			                  //Default recharge currency account
			                  accountMap.put("accountType", 1);
			                  accountMap.put("balance", sumCount);
			                int m = userAccountMapper.addBalance(accountMap);
			                //----Perform daily tasks----
			            	Map<String,Object> map = new HashMap<String,Object>();
			        		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
			        		String date = sdf.format(new Date());
			        		log.info("Current date: "+date);
			        		map.put("userId", receiveUserId);
			        		map.put("statisticsDate",date);
			        		map.put("taskDate",date);
			                DayTaskThread.startDayTask(InterfaceConstantUtil.PAY, map);
			                if(m>0){//Added successfully
			                	//Add recharge flow
			                	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); //The default recharge flow is recharge                	
		                        rechargeRecordMapper.insert(rechargeRecord);
			                }else{
			                	 log.info(out_trade_no+"------Failed to recharge account-----");
			                }
	              	 }else{
	              		 //Modify order status (failure)
		                 rechargeOrder.setState(Long.parseLong("0"));	
		                 rechargeOrderMapper.updateState(rechargeOrder);
		            	 log.info("------ Failed to modify order status-----");
	              	 }
              	
	            }else{
	            	 log.info("Illegal callback, the order amount is inconsistent with the callback amount.");
	              }
             }else{
              	log.info("Failed order");   
             }
		  } catch (Exception e) {
			   flag=false;
			e.printStackTrace ();
		  }
               return flag;
	 }

   Final tip: Just change the business logic inside to your own business logic. 

  Tools download address---click to arrive→

 The editor will not explain it in detail here. If you have any questions, comments should be written. If you still have questions, you can contact QQ985548426. The editor has been online for a long time.


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325169705&siteId=291194637