微信小程序支付+Java后台实现(完整版)

一,准备工作

appid=********  //小程序appid
mchid=********  //小程序绑定商户id
key=*****************  //商户后台设置的key

并在商户后天设置开发者选项,主要是设置回调域名。

二,Java后台代码编写

Controller层代码:

@RestController
@RequestMapping(value = "/payment/")
public class PaymentController {

	private static Logger logger = LoggerFactory.getLogger(PaymentController.class);
	@Value("${hcc.wx.domain}")
	private String orderDomain;
	
	@Autowired
	private PaymentService paymentService;

     /**
	 * <p>统一下单入口</p>
	 *
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@ResponseBody
    @RequestMapping(value="toPay", method=RequestMethod.POST, 
produces ={"application/json;charset=UTF-8"})
	public JSONObject toPay(HttpServletRequest request) throws Exception {
		String requestStr = RequestStr.getRequestStr(request);
		if (StringUtils.isEmpty(requestStr)) {
			throw new ParamException();
		}
		JSONObject jsonObj = JSONObject.parseObject(requestStr);
		if(StringUtils.isEmpty(jsonObj.getString("orderNo")) || StringUtils.isEmpty(jsonObj.getString("openId"))){
		   	throw new ParamException();
		}
	   	OrderInfo orderInfo = .....//此处写获取订单信息方法
	   	if(orderInfo == null){
	   		return AjaxUtil.renderFailMsg("订单不存在!");
	   	}else if(orderInfo.getPayAmount() == null || orderInfo.getPayAmount() <= 0){
	   		return AjaxUtil.renderFailMsg("订单有误,请确认!");
	   	}else if(orderInfo.getOrderStatus() != 1){//1待付款
	   		String msg = orderInfo.getOrderStatus() >1 ?"此订单已支付!":"订单未提交,请确认!";
	   		return AjaxUtil.renderFailMsg(msg);
	   	}else{
	   		logger.info("【小程序支付服务】请求订单编号:["+orderInfo.getOrderNo()+"]");
		   	Map<String, String> resMap = paymentService.xcxPayment(+orderInfo.getOrderNo(),orderInfo.getPayAmount(),jsonObj.getString("openId"));
		   	if("SUCCESS".equals(resMap.get("returnCode")) && "OK".equals(resMap.get("returnMsg"))){
		   		//统一下单成功
		   		resMap.remove("returnCode");
		   		resMap.remove("returnMsg");
		   		logger.info("【小程序支付服务】支付下单成功!");
		   		return AjaxUtil.renderSuccessMsg(resMap);
		   	}else{
		   		logger.info("【小程序支付服务】支付下单失败!原因:"+resMap.get("returnMsg"));
		   		return AjaxUtil.renderFailMsg(resMap.get("returnMsg"));
		   }
	   	}

	}
    /**
	 * <p>回调Api</p>
	 *
	 * @param request
	 * @param response
	 * @throws Exception
	 */
    @RequestMapping(value="xcxNotify")
	public void xcxNotify(HttpServletRequest request,HttpServletResponse response) throws Exception {
 		InputStream inputStream =  request.getInputStream();
 		//获取请求输入流
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len=inputStream.read(buffer))!=-1){
            outputStream.write(buffer,0,len);
        }
        outputStream.close();
        inputStream.close();
        Map<String,Object> map = BeanToMap.getMapFromXML(new String(outputStream.toByteArray(),"utf-8"));
        logger.info("【小程序支付回调】 回调数据: 
"+map);
        String resXml = "";
        String returnCode = (String) map.get("return_code");
        if ("SUCCESS".equalsIgnoreCase(returnCode)) {
            String returnmsg = (String) map.get("result_code");
            if("SUCCESS".equals(returnmsg)){
            	//更新数据
            	int result = paymentService.xcxNotify(map);
            	if(result > 0){
	            	//支付成功
	                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
	                        + "<return_msg><![CDATA[OK]]></return_msg>"+"</xml>";
            	}
            }else{
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]></return_msg>" + "</xml>";
                logger.info("支付失败:"+resXml);
            }
        }else{
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                    + "<return_msg><![CDATA[报文为空]></return_msg>" + "</xml>";
            logger.info("【订单支付失败】");
        }
        
        logger.info("【小程序支付回调响应】 响应内容:
"+resXml);
        response.getWriter().print(resXml);
	}
}

Service接口层代码(部分代码):

/**
* <p>支付接口层</p>
* 
* @author att  
* @date 2018年5月27日
* @since jdk1.8
* @version 1.0
 */
public interface PaymentService {

	Map<String,String> xcxPayment(String orderNo, double money,String openId) throws Exception;
	
	int xcxNotify(Map<String,Object> map) throws Exception;
}

Service接口实现(部分代码):

PayUtil工具类:

支付配置类:

Properties配置:

##config
xcx.pay.appid=wx**********
xcx.pay.mchid=*****
xcx.pay.key=**********

三,小程序端(获取统一下单返回参数发起支付)

测试一把:

经验分享 程序员 微信小程序 职场和发展