微信支付(app支付)(springboot实现 )

使用框架springboot 数据库 mysql 

阅读本文请先详细阅读微信文件  https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1(以统一下单为例)。

微信支付还是有很多坑的,在开发中还是需要和移动端或者前端多沟通,多交流方能解决。

微信支付接口签名校验工具 https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=20_1(下面会用到)

下面开始准备阶段,准备阶段是需要开发之前的一些准备工作,虽然看似简单,但是会影响后续的开发工作,所以这步也是重中之重。

微信app支付是不同于微信公众号支付的他是独立之外的所以申请时也要格外注意。

然后需要去商户平台去拿商户号以及key(api key ) 以及api证书

这是我的config文件这块还是有坑的后续还是需要优化的,appid、mac_id /api_key等文件是绝密是需要做处理的不应该这么显示。

做之前一定要有一个大概思路,而不应该乱,知道这步该干什么下步该干什么,做好有条不紊。

下面开始上代码,不上代码的程序员就是在耍流氓。

config层

 public  String app_id = "appid";

    /**
     * 商户号
     */
    public String mch_id = "商户号";

    /**
     * API 密钥
     */
//    
    public String key = "api秘钥";

    /**
     * API证书绝对路径 (本项目放在了 /src/resources/cert/wxpay/apiclient_cert.p12")
     */

    private String certPath = ClassUtils.getDefaultClassLoader().getResource("").getPath()+"/certificate/apiclient_cert.p12";

controller  这块我只截了一部分,里面的逻辑还需要自己处理。

@Autowired
    HttpServletRequest request;
    @ApiOperation(value = "微信支付统一下单", notes = "统一下单")
    @GetMapping("/unifiedOrder")
    @ResponseBody
    public ResponseResult<Object> unifiedOrder(HttpServletRequest request,
                @ApiParam(value = "订单号") @RequestParam String orderNum, @ApiParam(value = "订单金额") @RequestParam Double countsum,
                @ApiParam(value = "商品描述") @RequestParam String body, @ApiParam(value = "用户标识") @RequestParam Long memberId) {
         wxpayService.unifiedOrder(orderNum,countsum,body,memberId);
         }   
 

重点来了 servicempl

 @Override
    public Map<String, String> unifiedOrder(String orderNum, Double amount, String body,Long memberId) {
        System.out.println("--------------去支付------------------");
        Map<String, String> hashMap = new HashMap<>();
        final Logger logger = LoggerFactory.getLogger("MainLogger");
        final String SPBILL_CREATE_IP = "ip地址";
        final String NOTIFY_URL = "回调地址";
        final String TRADE_TYPE_APP = "APP";
        final Map<String, String> map = new HashMap<String, String>();
        try {
            WxchatpayConfig wxchatpayConfig = new WxchatpayConfig();
            map.put("appid", wxchatpayConfig.getAppID());          //应用Id
            map.put("mch_id", wxchatpayConfig.getMchID());         //商户号
            map.put("nonce_str",WXPayUtil.generateNonceStr());     //随机字符串
            map.put("body", body);                                 //商品描述
            map.put("out_trade_no",orderNum);                       //商户订单号
            map.put("total_fee","1");                            //总金额
            map.put("spbill_create_ip",SPBILL_CREATE_IP);          //终端ip
            StringBuffer notifyUrl = new StringBuffer();
            notifyUrl.append(NOTIFY_URL);
            if(memberId != null){
                notifyUrl.append("?member_id=").append(memberId);
            }
            //通知地址
            map.put("notify_url",NOTIFY_URL);
            //交易类型
            map.put("trade_type", "APP");
            String xml = WXPayUtil.generateSignedXml(map, wxchatpayConfig.getKey());
            logger.info("out_trade_no:" + orderNum + ",调用微信APP支付参数:" + xml);
            String res = pay(xml, "https://api.mch.weixin.qq.com/pay/unifiedorder");
            logger.info("out_trade_no:" + orderNum + ",调用微信APP支付返回:" + res);
            hashMap = WXPayUtil.xmlToMap(res);
            String currentTime = System.currentTimeMillis() / 1000 + "";
            Map<String, String> resultMap = new HashMap<>();
            resultMap.put("appid", wxchatpayConfig.getAppID());
            resultMap.put("partnerid",  wxchatpayConfig.getMchID());
            resultMap.put("prepayid", hashMap.get("prepay_id"));
            resultMap.put("package", "Sign=WXPay");
            resultMap.put("noncestr",WXPayUtil.generateNonceStr());
            resultMap.put("timestamp", currentTime);
            resultMap.put("sign",WXPayUtil.generateSignature(resultMap, 
            wxchatpayConfig.getKey()));
            return  resultMap;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hashMap;
    }


 /****
     * 支付
     * @param reqBody
     * @param url
     * @return
     * @throws Exception
     */
    private String pay(String reqBody, String url) throws Exception {
        String UTF8 = "UTF-8";
        URL httpUrl = new URL(url);
        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();
            }
        }
        return resp;
    }

敲黑板!!!!!

有的时候不只是仅仅要实现就行了,还得了解原理,能说出来,毕竟还要面试吗,做火箭的过程还是要有的,虽然生活处处都在拧螺丝,但是不要放弃,坚持。

如果你从头到尾按我的步骤走的那么此时你的接口应该可以被客户端调起来了

util类


public class WXPayUtil {

    /**
     * XML格式字符串转换为Map
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }

    }

  /**
     * 获取随机字符串 Nonce Str
     *
     * @return String 随机字符串
     */
    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }

   /**
     * 生成带有 sign 的 XML 格式字符串
     *
     * @param data Map类型数据
     * @param key API密钥
     * @param signType 签名类型
     * @return 含有sign字段的XML
     */

    public static String generateSignedXml(final Map<String, String> data, String key, WXPayConstants.SignType signType) throws Exception {
        String sign = generateSignature(data, key, signType);
        data.put(WXPayConstants.FIELD_SIGN, sign);
        return mapToXml(data);
    }
}

回调

 /****
     * @微信支付回调方法
     */
    @RequestMapping("/notify")
    @ResponseBody
    public String  payNotify(HttpServletRequest request) throws Exception {
        System.out.println("------------微信回调函数");
        ResponseResult responseResult = new ResponseResult<>();
        BufferedReader reader = null;
        reader = request.getReader();
        String line = "";
        String xmlString = null;
        StringBuffer inputString = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        reader.close();
        Map<String,String> map= WXPayUtil.xmlToMap(xmlString);
        for(String s:map.keySet()){
           System.out.println("微信回调信息为      =================KEY"+s+"=============="+map.get(s).toString());
        }
        String returnCode= map.get("return_code");
        if("SUCCESS".equals(returnCode)){
            String outTradeNo=map.get("out_trade_no");
            Order order= wxpayService.findOrder(outTradeNo);
            if(order!=null&& OrderConstant.UNPAID==order.getPayStatus()&&"SUCCESS".equals(map.get("result_code"))){
                Pay pay=new Pay();
                pay.setCreatAt(new Date());                       //创建时间
                pay.setOrderNum(outTradeNo);                      //订单号
                pay.setPayPrice(map.get("total_fee"));            //总金额
//                pay.setPayPrice((new BigDecimal(map.get("total_fee"))).divide(new BigDecimal("100")));
                pay.setBuyerAccounts(map.get("openid"));          //用户付款账号
                pay.setCode(Pay.class.getName());
                pay.setPayType(2);                                //支付方式  1.支付宝 2.微信
                pay.setPayStatus(PayReturnConstant.paySuccess);   //支付状态
                pay.setTr(1);                                     //状态
                long currentTimeMillis = DateTimeUtils.currentTimeMillis();
                pay.setPayTime(new Date(currentTimeMillis));      //支付时间
                pay.setTradeNo(map.get("transaction_id"));        //交易流水号
                wxpayService.add(pay);
                wxpayService.updateWechatPayStatus(outTradeNo);
            }
        }
        return "SUCCESS";
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值