java app微信支付

参考内容:

  1. 微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
  2. 微信官方demo:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

在正式敲代码之前,微信支付需要准备好应用id(appid)、appsecret、商户号(mchid)以及支付证书.
appid、appsecret在微信开放平台-管理中心-应用详情进行查看,appsecret可以重置.
mchid在微信开放平台-支付功能-已关联商户号进行查看.
支付证书则是在商户平台-账号中心-API安全进行下载.

  1. 先把官方demo下载下来
    在这里插入图片描述
    官方demo大概就是这些内容,其中也有对应的maven,先把这些文件复制到项目里
  2. 创建两个类PayAction和WXPayConfigImpl,对应代码如下
package com.solomo.sys.pay.wxpay;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.alibaba.fastjson.JSON;
import com.solomo.common.model.Orders;
import com.solomo.controller.orders.OrdersService;
import com.solomo.sys.DateUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class PayAction {
	
	private static Logger logger = Logger.getLogger(PayAction.class); 
	
	/**
	 * app统一下单
	 * @return
	 * @throws Exception
	 */
	public static Map<String, String> pay(Map<String, String> datas) throws Exception {
		String t = DateUtils.getNowTimeStamp().toString();
    	String timestamp = t.substring(0,t.length()-3);
		Map<String, String> data = new HashMap<String, String>();
		String notify_url = "http://192.168.0.107:8080/wakaka/orders/WXNotify";
        String UTF8 = "UTF-8";
        data.put("body", datas.get("body"));							// 商品描述
        data.put("out_trade_no", datas.get("out_trade_no"));			// 商户订单号
        data.put("device_info", "******");								// 设备号
        data.put("total_fee", datas.get("total_fee"));					// 总金额
        data.put("mch_id", WXPayConfigImpl.getInstance().getMchID());	// 商户号
        data.put("appid", WXPayConfigImpl.getInstance().getAppID());	// 应用ID
        data.put("nonce_str", WXPayUtil.generateNonceStr());			// 随机字符串
        data.put("fee_type", "CNY");									// 货币类型 CNY表示人民币
        data.put("spbill_create_ip", "192.168.0.107");					// 终端IP
        data.put("notify_url", notify_url);								// 通知地址
        data.put("trade_type", "APP");  								// 此处指定为app支付
        data.put("time_start", timestamp);								// 交易起始时间
        String sign = WXPayUtil.generateSignature(data, WXPayConfigImpl.getInstance().getKey());
        data.put("sign", sign);											// 签名
        String reqBody = WXPayUtil.mapToXml(data);
        boolean flag = WXPayUtil.isSignatureValid(data, WXPayConfigImpl.getInstance().getKey());
        logger.debug("签名是否正确:"+flag);
        URL httpUrl = new URL("https://api.mch.weixin.qq.com/pay/unifiedorder");
        HttpURLConnection httpURLConnection = (HttpURLConnection) httpUrl.openConnection();
        httpURLConnection.setRequestProperty("Host", "api.mch.weixin.qq.com");
        httpURLConnection.setDoOutput(true);
        httpURLConnection.setRequestMethod("POST");
        httpURLConnection.setConnectTimeout(10*1000);
        httpURLConnection.setReadTimeout(10*1000);
        httpURLConnection.connect();
        OutputStream outputStream = httpURLConnection.getOutputStream();
        outputStream.write(reqBody.getBytes(UTF8));

        //获取内容
        InputStream inputStream = httpURLConnection.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, UTF8));
        final StringBuffer stringBuffer = new StringBuffer();
        String line = null;
        while ((line = bufferedReader.readLine()) != null) {
            stringBuffer.append(line);
        }
        String resp = stringBuffer.toString();
        if (stringBuffer!=null) {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (inputStream!=null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (outputStream!=null) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logger.debug(resp);
        Map<String, String> result = WXPayUtil.xmlToMap(resp);
        String code = result.get("return_code");	// 返回状态码
        logger.debug(code);
        Map<String, String> data2 = new HashMap<String, String>();
        if( result.get("prepay_id") == null ){	
        	result.put("result_code", "FAIL");
        } else {
        	data2.put("appid", result.get("appid"));			// 应用APPID
        	data2.put("partnerid", result.get("mch_id"));		// 商户号
        	data2.put("prepayid", result.get("prepay_id"));		// 预支付交易会话标识
        	data2.put("package", "Sign=WXPay");
        	data2.put("noncestr", result.get("nonce_str"));		// 随机字符串
        	data2.put("timestamp", timestamp);
        	String secondSign = WXPayUtil.generateSignature(data2, WXPayConfigImpl.getInstance().getKey());
        	result.put("sign", secondSign);
        	result.put("timestamp", timestamp);
        }
        return result;
    }

	/**
	 * 接收微信支付成功通知   
	 * @param request
	 * @param response
	 * @throws IOException
	 */
    public static String getNotify(HttpServletRequest request,
                          HttpServletResponse response)
            throws IOException {
        System.out.println("微信支付回调");
        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();
        String result = new String(outSteam.toByteArray(), "utf-8");
        logger.debug("微信支付通知结果:" + result);
        Map<String, String> map = null;
        /**
         * 解析微信通知返回的信息
         */
        try {
			map = WXPayUtil.xmlToMap(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
        String notifyStr = null;
        boolean flag = false;
        try {
			flag = WXPayUtil.isSignatureValid(map, WXPayConfigImpl.getInstance().getKey());
			logger.debug("微信验证通知结果:"+flag);
			if(!flag ){
				notifyStr = WXPayUtil.setXML("FALSE", "FAIL");
				return notifyStr;  
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
        logger.debug("=========================================");
        logger.info("微信支付:"+JSON.toJSONString(map));
		logger.debug("=========================================");
        // 若支付成功,则告知微信服务器收到通知
        if (map.get("return_code").equals("SUCCESS")) {	
       	    //微信支付成功  开始业务处理
        	 ......
        	 ......
        }else{
        	notifyStr = WXPayUtil.setXML("FALSE", "FAIL");
        } 
        return notifyStr;  
    }
    
    public static boolean orderQuery(String out_trade_no) throws Exception{
    	boolean flag = false;
    	WXPay wxpay;
    	WXPayConfig config;
    	config = WXPayConfigImpl.getInstance();
		wxpay = new WXPay(config);
    	HashMap<String, String> map = new HashMap<String, String>();
    	map.put("out_trade_no", out_trade_no);
    	Map<String,String> result = wxpay.orderQuery(map);
    	System.out.println(JSON.toJSONString(result));
    	if( result.get("return_code").equals("SUCCESS")){
    		if(result.get("trade_state").equals("SUCCESS")){
    			flag = true;
    		}
    	}
    	return flag;
    }
    
    public static void main(String[] args) {
    	try {
			orderQuery("32f8dfc373f848158804a29be008b058");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

package com.solomo.sys.pay.wxpay;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class WXPayConfigImpl extends WXPayConfig{

    private byte[] certData;
    private static WXPayConfigImpl INSTANCE;

    private WXPayConfigImpl() throws Exception{
    	//微信支付证书
        String certPath = "D://CERT/common/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 static WXPayConfigImpl getInstance() throws Exception{
        if (INSTANCE == null) {
            synchronized (WXPayConfigImpl.class) {
                if (INSTANCE == null) {
                    INSTANCE = new WXPayConfigImpl();
                }
            }
        }
        return INSTANCE;
    }

    //appid
    public String getAppID() {
        return "***********************";
    }
    //商户id
    public String getMchID() {
        return "***********************";
    }
    //key
    public String getKey() {
        return "***********************";
    }

    public InputStream getCertStream() {
        ByteArrayInputStream certBis;
        certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    public int getHttpConnectTimeoutMs() {
        return 2000;
    }

    public int getHttpReadTimeoutMs() {
        return 10000;
    }

    IWXPayDomain getWXPayDomain() {
        return WXPayDomainSimpleImpl.instance();
    }

    public String getPrimaryDomain() {
        return "api.mch.weixin.qq.com";
    }

    public String getAlternateDomain() {
        return "api2.mch.weixin.qq.com";
    }

    @Override
    public int getReportWorkerNum() {
        return 1;
    }

    @Override
    public int getReportBatchSize() {
        return 2;
    }
}

/**
 * 微信支付结果异步通知
 */
public void WXNotify() {
	String result = null;
	try {
		result = com.solomo.sys.pay.wxpay.PayAction.getnotify(getRequest(), getResponse());
	} catch (IOException e) {
		e.printStackTrace();
	}
	renderText(result);
	return;
}

PayAction中主要是pay和getNotify这两个接口,pay方法中需要替换的有notify_url,对应的是第三段代码的路径;还有spbill_create_ip表示的是终端ip,需要修改成自己的ip,其他的如果需要修改可根据注释自行修改,WXPayConfigImpl中把最开始准备的信息放进去即可.

  1. 开始使用,代码如下
public void paymentExchange() throws Exception {
	JSONObject jsonObject = new JSONObject();
	String ordersId = getPara("ordersId");
	String rewardId = getPara("rewardId");
	String payType = getPara("payType");	// 支付类型 0微信支付 1支付宝支付
	Orders orders = ordersService.findInfoById(ordersId);
	orders.set("payType", payType).update();
	Reward reward = rewardService.findInfoById(rewardId);
	String content = "兑换"+reward.getStr("name");
	double price = 0.01;	// 默认价格单位:元
	Map<String, String> data = new HashMap<String, String>();
	data.put("body", content);
	data.put("out_trade_no", orders.getStr("id"));
	Map<String, String> map = new HashMap<String, String>();
	if ("0".equals(payType)) {	// 微信支付
		String prices = price*100+"";
		data.put("total_fee", prices.substring(0, prices.indexOf(".")));	// 微信sdk中金额的默认单位是分
		map = com.solomo.sys.pay.wxpay.PayAction.pay(data);
		jsonObject.put("result", map);
	} else {  // 支付宝支付
		data.put("total_fee", price+"");
		AlipayTradeAppPayResponse response = com.solomo.sys.pay.alipay.PayAction.pay(data);
		jsonObject.put("result", response.getBody());
	}
	String msg = map.get("return_code");
	jsonObject.put("msg", msg);
	jsonObject.put("code", 1);
	renderJson(jsonObject.toJSONString());
	return;
}

以金额和商品描述这两个参数直接调用即可,支付宝支付可查看:https://blog.csdn.net/weixin_43886319/article/details/94725850

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值