Search in sources :

Example 1 with WeixinHttpCallback

use of com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback in project weixin-boot by guhanjie.

the class MessageKit method sendKFMsg.

public static void sendKFMsg(String openids, String content) {
    if (StringUtils.isBlank(openids)) {
        LOGGER.warn("send order msg to KF, but no kf openids.");
        return;
    }
    String[] ids = openids.split(",");
    for (final String openid : ids) {
        LOGGER.info("starting to send message to KF[{}]...", openid);
        try {
            String url = WeixinConstants.API_KF_SEND_MSG;
            String str = new String("{" + "    \"touser\":\"OPENID\"," + "    \"msgtype\":\"text\"," + "    \"text\":" + "    {" + "         \"content\":\"ContentText\"" + "    }" + "}");
            str = str.replaceAll("OPENID", openid);
            str = str.replaceAll("ContentText", content);
            LOGGER.debug("message content: [{}]", str);
            HttpEntity entity = new StringEntity(str, ContentType.APPLICATION_JSON);
            WeixinHttpUtil.sendPost(url, entity, new WeixinHttpCallback() {

                @Override
                public void process(String json) {
                    ErrorEntity t = JSONObject.parseObject(json, ErrorEntity.class);
                    if (t != null && t.getErrcode() != null && t.getErrmsg() != null) {
                        if (t.getErrcode().equals("0") && t.getErrmsg().equals("ok"))
                            LOGGER.info("Success to post message to KF[{}].", openid);
                        return;
                    }
                    LOGGER.error("Failed to post message to KF, error:[{}].", json);
                }
            });
        } catch (Exception e) {
            LOGGER.error("error to post message[{}] to KF[{}].", content, openid);
        }
    }
}
Also used : StringEntity(org.apache.http.entity.StringEntity) HttpEntity(org.apache.http.HttpEntity) ErrorEntity(com.guhanjie.weixin.model.ErrorEntity) IOException(java.io.IOException) WeixinHttpCallback(com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)

Example 2 with WeixinHttpCallback

use of com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback in project weixin-boot by guhanjie.

the class PayKit method search.

/**
 * Method Name:	search<br/>
 * Description:			[该接口提供所有微信支付订单的查询,商户可以通过查询订单接口主动查询订单状态,完成下一步的业务逻辑。]<br/>
 * 								需要调用查询接口的情况:<br/>
 * 								◆ 当商户后台、网络、服务器等出现异常,商户系统最终未接收到支付通知;<br/>
 * 								◆ 调用支付接口后,返回系统错误或未知交易状态情况;<br/>
 *								◆ 调用被扫支付API,返回USERPAYING的状态;<br/>
 * 								◆ 调用关单或撤销接口API之前,需确认支付状态;
 * @author				GUHANJIE
 * @time					2016年9月30日 下午2:25:42
 * @param orderid
 * @param appid
 * @param mchid
 * @param mchkey
 * @return Map<K,V>: {<br/>result: SUCCESS/FAIL, <br/>out_trade_no: orderid, <br/>total_fee: 100, time_end: ***, <br/>openid:***<br/>}
 * @throws IOException
 */
public static Map<String, String> search(final Order order, final String appid, final String mchid, final String mchkey) throws IOException {
    if (order == null) {
        LOGGER.warn("order can not be nulll in search order.");
        return null;
    }
    LOGGER.info("starting to search payment for order:[{}]...", order.getId());
    final Map<String, String> result = new HashMap<String, String>();
    result.put("out_trade_no", String.valueOf(order.getId()));
    final String nonceStr = String.valueOf(new Random().nextInt(10000));
    Map<String, String> map = new HashMap<String, String>();
    // 公众账号ID
    map.put("appid", appid);
    // 商户号
    map.put("mch_id", mchid);
    // 商户订单号
    map.put("out_trade_no", String.valueOf(order.getId()));
    // 随机字符串
    map.put("nonce_str", nonceStr);
    // 签名
    map.put("sign", sign(map, mchkey));
    String reqStr = XmlUtil.map2xmlstr(map);
    LOGGER.debug("=====set request for weixin search payment:[{}].", reqStr);
    HttpEntity entity = new StringEntity(reqStr, ContentType.create("application/xml", Consts.UTF_8));
    WeixinHttpUtil.sendPost(WeixinConstants.API_PAY_ORDERQUERY, entity, new WeixinHttpCallback() {

        @Override
        public void process(String respBody) {
            Map<String, String> map = XmlUtil.xmlstr2map(respBody);
            LOGGER.debug("=====got response from weixin search payment:[{}].", map);
            // 返回状态码SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
            String return_code = map.get("return_code");
            // 返回信息
            String return_msg = map.get("return_msg");
            if (!"SUCCESS".equals(return_code)) {
                LOGGER.error("fail to get response for weixin search payment api, cause:[{}]", return_msg);
                result.put("result", return_code);
                result.put("err_msg", "订单查询失败: " + return_msg);
                return;
            }
            // 验签
            String signature = sign(map, mchkey);
            // 签名
            String sign = map.get("sign");
            if (sign == null || !sign.equals(signature)) {
                LOGGER.warn("signature validation failed, this response maybe fake!");
                result.put("result", "FAIL");
                result.put("err_msg", "验签失败");
                return;
            }
            // 验证随机字符串nonce,防CSRF攻击
            // String nonce_str = map.get("nonce_str");                                            //随机字符串
            // if(!nonceStr.equals(nonce_str)) {
            // LOGGER.warn("nonce not matched(CSRF warning), this response maybe fake!");
            // result.put("result", "FAIL");
            // result.put("err_msg", "随机字符串不匹配");
            // return;
            // }
            // 根据业务结果,执行后续业务操作
            // 业务结果
            String result_code = map.get("result_code");
            if (!"SUCCESS".equals(result_code)) {
                // 错误代码
                String err_code = map.get("err_code");
                // 错误代码描述
                String err_code_des = map.get("err_code_des");
                LOGGER.error("error in weixin search payment, cause: err_code=[{}], err_code_des=[{}]", err_code, err_code_des);
                result.put("result", result_code);
                result.put("err_msg", "pay search fail: " + err_code + ", " + err_code_des);
                return;
            }
            // 用户OpenId
            String openid = map.get("openid");
            // 交易状态(SUCCESS—支付成功、REFUND—转入退款、NOTPAY—未支付、CLOSED—已关闭、REVOKED—已撤销(刷卡支付)、USERPAYING--用户支付中、PAYERROR--支付失败(其他原因,如银行返回失败)、)
            String trade_state = map.get("trade_state");
            // 商户订单号
            String out_trade_no = map.get("out_trade_no");
            // 订单总金额,单位为分
            String total_fee = map.get("total_fee");
            // 支付完成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。
            String time_end = map.get("time_end");
            // 对当前查询订单状态的描述和下一步操作的指引
            String trade_state_desc = map.get("trade_state_desc");
            // String settlement_total_fee = map.get("settlement_total_fee");		//应结订单金额=订单金额-非充值代金券金额,应结订单金额<=订单金额
            // String transaction_id = map.get("transaction_id");						//微信支付订单号
            // String appid = map.get("appid");                                                        //公众账号ID
            // String mch_id = map.get("mch_id");                                                  //商户号
            // String device_info = map.get("device_info");                                        //设备号
            // String is_subscribe = map.get("is_subscribe");                                //用户是否关注公众账号,Y-关注,N-未关注,仅在公众账号类型支付有效
            // String trade_type = map.get("trade_type");                                  //交易类型JSAPI
            // String bank_type = map.get("bank_type");                                     //付款银行(银行类型,采用字符串类型的银行标识)
            // String fee_type = map.get("fee_type");											//货币种类
            // String cash_fee = map.get("cash_fee");											//货币种类
            LOGGER.info("success to search weixin payment for order:[{}]: " + "openid=[{}], trade_state=[{}], total_fee=[{}], out_trade_no=[{}], time_end=[{}], trade_state_desc=[{}]", order.getId(), openid, trade_state, total_fee, out_trade_no, time_end, trade_state_desc);
            if (!"SUCCESS".equals(trade_state)) {
                // 支付不成功
                LOGGER.warn("trade failed, trade_state:[{}], trade_state_desc:[{}]", trade_state, trade_state_desc);
                result.put("result", trade_state);
                result.put("err_msg", "订单支付不成功:" + trade_state_desc);
                return;
            }
            if (order.getAmount().intValue() != Integer.valueOf(total_fee) / 100) {
                // 支付金额与订单金额不一致
                LOGGER.warn("trade exception, amount not matched: topay=[{}], payed=[{}]", order.getAmount(), total_fee);
            // result.put("result", "FAIL");
            // result.put("err_msg", "订单支付金额有误:topay="+order.getAmount()+", payed="+ total_fee);
            // return;
            }
            result.put("total_fee", total_fee);
            result.put("time_end", time_end);
            result.put("openid", openid);
            result.put("result", "SUCCESS");
        }
    });
    return result;
}
Also used : StringEntity(org.apache.http.entity.StringEntity) Random(java.util.Random) HttpEntity(org.apache.http.HttpEntity) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) WeixinHttpCallback(com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)

Example 3 with WeixinHttpCallback

use of com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback in project weixin-boot by guhanjie.

the class MediaKit method postMedia.

public static String postMedia(String path, String type) {
    LOGGER.debug("starting to post media: path[{}] type[{}]...", path, type);
    final WeixinMedia wm = new WeixinMedia();
    try {
        String url = WeixinConstants.API_POST_MEDIA;
        url = url.replace("TYPE", type);
        FileBody fb = new FileBody(new File(path));
        HttpEntity entity = MultipartEntityBuilder.create().addPart("media", fb).build();
        WeixinHttpUtil.sendPost(url, entity, new WeixinHttpCallback() {

            @Override
            public void process(String json) {
                WeixinMedia t = JSONObject.parseObject(json, WeixinMedia.class);
                if (t != null && t.getMedia_id() != null) {
                    wm.setMedia_id(t.getMedia_id());
                    LOGGER.info("Success to post media:[{}].", t.getMedia_id());
                } else {
                    LOGGER.error("Failed to post media.");
                }
            }
        });
    } catch (Exception e) {
        LOGGER.error("error post media: type[{}], path[{}]", type, path);
    }
    return wm.getMedia_id();
}
Also used : WeixinMedia(com.guhanjie.weixin.model.WeixinMedia) FileBody(org.apache.http.entity.mime.content.FileBody) HttpEntity(org.apache.http.HttpEntity) File(java.io.File) WeixinHttpCallback(com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)

Example 4 with WeixinHttpCallback

use of com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback in project weixin-boot by guhanjie.

the class PayKit method unifiedorder.

/**
 * Method Name:	unifiedorder<br/>
 * Description:			[除被扫支付场景以外,商户系统先调用该接口在微信支付服务后台生成预支付交易单,
 *                              返回正确的预支付交易回话标识后再按扫码、JSAPI、APP等不同场景生成交易串调起支付。]
 * @author				guhanjie
 * @time					2016年9月30日 上午1:39:12
 * @param request
 * @param order
 * @param appid
 * @param mchid
 * @throws IOException
 */
public static String unifiedorder(HttpServletRequest request, final Order order, final String appid, final String mchid, final String mchkey) throws IOException {
    if (order == null) {
        LOGGER.warn("order can not be nulll in unified order.");
        return null;
    }
    LOGGER.info("starting to unified order to weixin for order:[{}]...", order.getId());
    final StringBuilder prepayId = new StringBuilder();
    final String nonceStr = String.valueOf(new Random().nextInt(10000));
    Map<String, String> map = new HashMap<String, String>();
    // 公众账号ID
    map.put("appid", appid);
    // 商户号
    map.put("mch_id", mchid);
    // 设备号(PC网页或公众号内支付请传"WEB")
    map.put("device_info", "WEB");
    // 随机字符串
    map.put("nonce_str", nonceStr);
    // 商品描述
    map.put("body", "上海尊涵搬家-搬家服务");
    // map.put("detail", "商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。");          //商品详情
    // map.put("attach", "附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据");
    // 商户订单号
    map.put("out_trade_no", order.getId().toString());
    // 货币类型
    map.put("fee_type", "CNY");
    int money = order.getAmount().intValue() * 100;
    if (order.getTip() != null) {
        money += order.getTip().intValue() * 100;
    }
    // 总金额,订单总金额,单位为分
    map.put("total_fee", String.valueOf(money));
    // 用户端IP
    map.put("spbill_create_ip", HttpUtil.getIpAddress(request));
    // 交易起始时间,格式为yyyyMMddHHmmss
    map.put("time_start", new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA).format(new Date()));
    // map.put("time_expire", "订单失效时间,格式为yyyyMMddHHmmss,最短失效时间间隔必须大于5分钟");                       //交易结束时间
    // map.put("goods_tag", "WXG");                                                          //商品标记
    // 通知地址,接收微信支付异步通知回调地址
    map.put("notify_url", WeixinConstants.API_PAY_CALLBACK);
    // 交易类型
    map.put("trade_type", "JSAPI");
    // map.put("product_id", "此id为二维码中包含的商品ID,商户自行定义");//商品ID
    // map.put("limit_pay", "no_credit--指定不能使用信用卡支付");               //支付方式
    // 用户标识
    map.put("openid", (String) request.getSession().getAttribute(AppConstants.SESSION_KEY_OPEN_ID));
    // 签名
    map.put("sign", sign(map, mchkey));
    String reqOrderStr = XmlUtil.map2xmlstr(map);
    LOGGER.debug("=====set request for weixin unified order:[{}].", reqOrderStr);
    HttpEntity entity = new StringEntity(reqOrderStr, ContentType.create("application/xml", Consts.UTF_8));
    WeixinHttpUtil.sendPost(WeixinConstants.API_PAY_UNIFIEDORDER, entity, new WeixinHttpCallback() {

        @Override
        public void process(String respBody) {
            Map<String, String> map = XmlUtil.xmlstr2map(respBody);
            LOGGER.debug("=====got response from weixin unified order:[{}].", map);
            // 返回状态码SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
            String return_code = map.get("return_code");
            // 返回信息
            String return_msg = map.get("return_msg");
            // 公众账号ID
            String appid = map.get("appid");
            // 商户号
            String mch_id = map.get("mch_id");
            // 设备号
            String device_info = map.get("device_info");
            // 随机字符串
            String nonce_str = map.get("nonce_str");
            // 签名
            String sign = map.get("sign");
            // 业务结果
            String result_code = map.get("result_code");
            // 错误代码
            String err_code = map.get("err_code");
            // 错误代码描述
            String err_code_des = map.get("err_code_des");
            // 交易类型JSAPI
            String trade_type = map.get("trade_type");
            // 预支付交易会话ID
            String prepay_id = map.get("prepay_id");
            // 二维码链接
            String code_url = map.get("code_url");
            if (!"SUCCESS".equals(return_code)) {
                LOGGER.error("fail to get response for weixin unified order api, cause:[{}]", return_msg);
                return;
            }
            // 验签
            String signature = sign(map, mchkey);
            if (sign == null || !sign.equals(signature)) {
                LOGGER.warn("signature validation failed, this response maybe fake!");
                return;
            }
            // 根据业务结果,执行后续业务操作
            if (!"SUCCESS".equals(result_code)) {
                LOGGER.error("error in weixin unified order, cause: err_code=[{}], err_code_des=[{}]", err_code, err_code_des);
                return;
            }
            // 成功,则返回JSAPI需要的预支付ID
            prepayId.append(prepay_id);
            LOGGER.info("success to get weixin prepay id:[{}] for order:[{}]", prepay_id, order.getId());
        }
    });
    return prepayId.toString();
}
Also used : HttpEntity(org.apache.http.HttpEntity) HashMap(java.util.HashMap) Date(java.util.Date) StringEntity(org.apache.http.entity.StringEntity) Random(java.util.Random) SimpleDateFormat(java.text.SimpleDateFormat) HashMap(java.util.HashMap) Map(java.util.Map) WeixinHttpCallback(com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)

Example 5 with WeixinHttpCallback

use of com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback in project weixin-boot by guhanjie.

the class PayKit method closeorder.

/**
 * Method Name:	closeorder<br/>
 * Description:			[关单接口,以下情况需要调用]:<br/>
 *                            ◆ 商户订单支付失败需要生成新单号重新发起支付,要对原订单号调用关单,避免重复支付;<br/>
 *                            ◆ 系统下单后,用户支付超时,系统退出不再受理,避免用户继续,请调用关单接口。<br/>
 *                        <b>注意:订单生成后不能马上调用关单接口,最短调用时间间隔为5分钟。</b>
 * @author				guhanjie
 * @time					2016年10月16日 下午7:00:56
 */
public static boolean closeorder(final Order order, final String appid, final String mchid, final String mchkey) throws IOException {
    if (order == null) {
        LOGGER.warn("order can not be nulll in close order.");
        return false;
    }
    LOGGER.info("starting to close payment for order:[{}]...", order.getId());
    final StringBuilder result = new StringBuilder("");
    final String nonceStr = String.valueOf(new Random().nextInt(10000));
    Map<String, String> map = new HashMap<String, String>();
    // 公众账号ID
    map.put("appid", appid);
    // 商户号
    map.put("mch_id", mchid);
    // 商户订单号
    map.put("out_trade_no", String.valueOf(order.getId()));
    // 随机字符串
    map.put("nonce_str", nonceStr);
    // 签名
    map.put("sign", sign(map, mchkey));
    String reqStr = XmlUtil.map2xmlstr(map);
    LOGGER.debug("=====set request for weixin search payment:[{}].", reqStr);
    HttpEntity entity = new StringEntity(reqStr, ContentType.create("application/xml", Consts.UTF_8));
    WeixinHttpUtil.sendPost(WeixinConstants.API_PAY_CLOSEORDER, entity, new WeixinHttpCallback() {

        @Override
        public void process(String respBody) {
            Map<String, String> map = XmlUtil.xmlstr2map(respBody);
            LOGGER.debug("=====got response from weixin close payment:[{}].", map);
            // 返回状态码SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断
            String return_code = map.get("return_code");
            // 返回信息
            String return_msg = map.get("return_msg");
            if (!"SUCCESS".equals(return_code)) {
                LOGGER.error("fail to get response for weixin close payment api, cause:[{}]", return_msg);
                return;
            }
            // 验签
            String signature = sign(map, mchkey);
            // 签名
            String sign = map.get("sign");
            if (sign == null || !sign.equals(signature)) {
                LOGGER.warn("signature validation failed, this response maybe fake!");
                return;
            }
            // 验证随机字符串nonce,防CSRF攻击
            // String nonce_str = map.get("nonce_str");                                            //随机字符串
            // if(!nonceStr.equals(nonce_str)) {
            // LOGGER.warn("nonce not matched(CSRF warning), this response maybe fake!");
            // result.put("result", "FAIL");
            // result.put("err_msg", "随机字符串不匹配");
            // return;
            // }
            // 根据业务结果,执行后续业务操作
            // 业务结果
            String result_code = map.get("result_code");
            if (!"SUCCESS".equals(result_code)) {
                // 错误代码
                String err_code = map.get("err_code");
                // 错误代码描述
                String err_code_des = map.get("err_code_des");
                LOGGER.error("error in weixin close payment, cause: err_code=[{}], err_code_des=[{}]", err_code, err_code_des);
                return;
            }
            LOGGER.info("success to close weixin payment for order[{}].", order.getId());
            result.append("success");
        }
    });
    return "success".equals(result.toString());
}
Also used : StringEntity(org.apache.http.entity.StringEntity) Random(java.util.Random) HttpEntity(org.apache.http.HttpEntity) HashMap(java.util.HashMap) HashMap(java.util.HashMap) Map(java.util.Map) WeixinHttpCallback(com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)

Aggregations

WeixinHttpCallback (com.guhanjie.weixin.WeixinHttpUtil.WeixinHttpCallback)9 HttpEntity (org.apache.http.HttpEntity)5 StringEntity (org.apache.http.entity.StringEntity)4 UserInfo (com.guhanjie.weixin.model.UserInfo)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 Random (java.util.Random)3 AccessToken (com.guhanjie.weixin.model.AccessToken)2 IOException (java.io.IOException)2 Date (java.util.Date)2 User (com.guhanjie.model.User)1 ErrorEntity (com.guhanjie.weixin.model.ErrorEntity)1 WeixinMedia (com.guhanjie.weixin.model.WeixinMedia)1 File (java.io.File)1 SimpleDateFormat (java.text.SimpleDateFormat)1 HttpServletResponse (javax.servlet.http.HttpServletResponse)1 HttpSession (javax.servlet.http.HttpSession)1 FileBody (org.apache.http.entity.mime.content.FileBody)1 Scheduled (org.springframework.scheduling.annotation.Scheduled)1 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)1