淘先锋技术网

首页 1 2 3 4 5 6 7

首先,参考文档:

【微信支付】H5支付开发文档
Java 后端微信支付demo

  1. 引入jar包
		<dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>0.0.3</version>
        </dependency>
  1. 配置申请好的AppId,MchId, Key

这里只需要统一下单、支付回调以及查询订单,所以不需要加载证书

import com.github.wxpay.sdk.WXPayConfig;

import java.io.InputStream;

/** 配置我们自己的信息  */

public class WxPayConfig implements WXPayConfig {

//    /** 加载证书  这里证书需要到微信商户平台进行下载*/
//    private byte [] certData;
//
//    public WxPayConfig() throws  Exception{
//        InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("../cert/pay/apiclient_cert.p12");
//        this.certData = IOUtils.toByteArray(certStream);
//        certStream.close();
//    }

    /** 设置我们自己的appid
     * 商户号
     * 秘钥
     * */

    @Override
    public String getAppID() {
        return "###AppId";
    }

    @Override
    public String getMchID() {
        return "###MchId";	
    }

    @Override
    public String getKey() {
        return "###Key";
    }

    @Override
    public InputStream getCertStream() {
        return null;
    }

    @Override
    public int getHttpConnectTimeoutMs() {
        return 0;
    }

    @Override
    public int getHttpReadTimeoutMs() {
        return 0;
    }
}
  1. 统一下单接口示例:
 	// 微信支付下单
    @PreAuthorize("@el.check('anonymous')") // 匿名访问
    @PostMapping("/prePay")
    public ResponseEntity placeOrder(HttpServletRequest request, @RequestBody Map params) throws Exception {

        // 保存订单并返回订单号 shopOrderDTO.getId()

        // 处理请求参数
        WxPayConfig wxPayConfig = new WxPayConfig();
        WXPay wxPay = new WXPay(wxPayConfig);
        String url = "###公网地址";
        String notifyUrl = url + "/payReturn";	// 微信支付回调地址,详情参考微信官方文档要求

        Map<String,String> data = new HashMap<>();
        data.put("out_trade_no", shopOrderDTO.getId()+"");   //订单编号
        data.put("total_fee",params.get("total_free").toString());   //金额(单位为分) int
        data.put("attach", new JSONObject().toJSONString(attach));  //附加数据:{nums:1, device_id:"0x234143", store_id:10000000}

        data.put("appid",wxPayConfig.getAppID());
        data.put("mch_id",wxPayConfig.getMchID());
        data.put("trade_type","MWEB");	// h5支付固定写法
        data.put("device_info","WEB"); // h5支付固定写法
        data.put("notify_url",notifyUrl);
        data.put("spbill_create_ip", IPUtil.getIPAddress(request));
        data.put("fee_type","CNY");
        data.put("body","###支付信息描述");
        data.put("nonce_str", WXPayUtil.generateNonceStr()); 
        data.put("scene_info", "###参考官方文档");
        // 生成签名
        String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
        data.put("sign",s);

        // 发起下单请求
        Map<String, String> respData = wxPay.unifiedOrder(data);

        // 处理下单结果
        if (respData.get("return_code").equals("SUCCESS")){
            if (respData.get("result_code").equals("SUCCESS")) {
                respData.put("out_trade_no", shopOrderDTO.getId()+"");
                return new ResponseEntity<>(respData, HttpStatus.OK);
            } else {
                // 下单失败的处理 如保存日志
                throw new Exception(respData.get("err_code_des"));
            }
        } else {
        	// 下单失败的处理 如保存日志
            throw new Exception(respData.get("return_msg"));
        }

    }
  1. 支付回调接口
    // 微信支付回调
    @PreAuthorize("@el.check('anonymous')")
    @RequestMapping("/payReturn")
    public String payReturn(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // logger.info("微信支付回调:");

        WxPayConfig wxPayConfig = new WxPayConfig();
        WXPay wxPay = new WXPay(wxPayConfig);

        // 接收请求参数
        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);
        }
        String xml = new String(outSteam.toByteArray(), "utf-8");
        // 转为Map
        Map<String, String> params = WXPayUtil.xmlToMap(xml);
        outSteam.close();
        inStream.close();

        // 验证签名
        if (wxPay.isResponseSignatureValid(params)) { 

            if (params.get("return_code").equals("FAIL")) {

                shopLogService.anonymousCreate(shopLogService.getShopLog(null, null, "支付发起失败",params.get("return_msg") + "" ));

            } else if (params.get("return_code").equals("SUCCESS")){

                if (params.get("result_code").equals("FAIL")) {

                    // 支付失败

                } else if (params.get("result_code").equals("SUCCESS")) {

                    // 查询订单,将支付返回结果与订单保存信息对比
                    ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(params.get("out_trade_no")));	

					// 判断金额、订单支付状态、支付结果
                    if (orderDTO.getAmount() == Integer.valueOf(params.get("total_fee")) && orderDTO.getState() == 1
                            && !StringUtils.isBlank(params.get("transaction_id"))) {

                        // 修改订单状态为已支付 省略
                        
                        return "<xml>\n" +
                                "  <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                                "  <return_msg><![CDATA[OK]]></return_msg>\n" +
                                "</xml>";

                    } else if (StringUtils.isBlank(params.get("transaction_id"))){
                        // 支付ID为空
                    } else if (orderDTO.getState() == 0){
                        // 订单状态为已支付
                    } else if (orderDTO.getAmount() != Integer.valueOf(params.get("total_fee"))){
                        // 支付金额与订单金额不相等
                    }
                }
            }
        }
        return "";
    }

  1. 查询订单接口
    // 微信支付查询 参数是订单id
    @PreAuthorize("@el.check('anonymous')")
    @RequestMapping("/paySearch")
    public Map paySearch(String id) throws Exception {
		
		// 查询订单
        ShopOrderDTO orderDTO = shopOrderService.findById(Long.valueOf(id));

		// 如果订单已支付且支付id不为空,可以直接返回结果
        if (orderDTO.getState() == 0 && !StringUtils.isBlank(orderDTO.getPayId())) {
            Map<String, String> result = new HashMap<>();
            result.put("return_code", "SUCCESS");
            result.put("result_code", "SUCCESS");
            result.put("trade_state", "SUCCESS");
            return result;
        } else {
        	// 处理参数
            WxPayConfig wxPayConfig = new WxPayConfig();
            WXPay wxPay = new WXPay(wxPayConfig);
            Map<String,String> data = new HashMap<>();
            data.put("out_trade_no", id);   //订单编号
            data.put("appid",wxPayConfig.getAppID());
            data.put("mch_id",wxPayConfig.getMchID());
            data.put("nonce_str", WXPayUtil.generateNonceStr()); 
            // 签名
            String s = WXPayUtil.generateSignature(data, wxPayConfig.getKey());
            data.put("sign",s);
            // 发起查询
            Map<String, String> result = wxPay.orderQuery(data);
			
			// 如果用户已支付
            if (result.get("return_code").equals("SUCCESS") && result.get("result_code").equals("SUCCESS") && result.get("trade_state").equals("SUCCESS")) {
                // 修改订单支付状态和支付id
            }
            return result;
        }
    }