zoukankan      html  css  js  c++  java
  • 微信小程序,调用建行支付。

    由于微信支付费率是千分之六,在得知道建行龙支付可以做到千分之二,公司在成本这块就果断采取接建行,废话不说了直接贴代码

    Service 层 

    相关的参数要求还得细对建行的文档

    @Service
    public class CCBPayServiceImpl implements CCBPayApi {
        private static final Logger LOGGER = LoggerFactory.getLogger(CCBPayServiceImpl.class);
    
        @Override
        public PayResult cCBPayment(PayRequestInfo payRequestInfo) throws BizException {
            BigDecimal orderPrice = TypeConversionUtil.getBigDecimal(payRequestInfo.getOrderPrice());
            HashMap<String, String> map = new HashMap<String, String>();
            map.put("MERCHANTID", CCBConstants.MERCHANTID);
            map.put("POSID", CCBConstants.POSID);
            map.put("BRANCHID", CCBConstants.BRANCHID);
            map.put("ORDERID", payRequestInfo.getOrderNo());
            map.put("PAYMENT", orderPrice.toString());
            map.put("CURCODE", CCBConstants.CURCODE);
            map.put("REMARK1", CCBConstants.REMARK1);
            map.put("REMARK2", CCBConstants.REMARK2);
            map.put("TXCODE", CCBConstants.TXCODE);
            map.put("TYPE", CCBConstants.TYPE);
            map.put("GATEWAY", CCBConstants.GATEWAY);
            map.put("CLIENTIP", payRequestInfo.getSpbillCreateIp());
            map.put("REGINFO", CCBConstants.REGINFO);
            map.put("PROINFO", CCBConstants.PROINFO);
            map.put("REFERER", CCBConstants.REFERER);
            // map.put("TIMEOUT", null);
            map.put("TRADE_TYPE", payRequestInfo.getTradeType());
            map.put("SUB_APPID", payRequestInfo.getAppId());
            map.put("SUB_OPENID", payRequestInfo.getOpenId());
            // MD5加密
            StringBuilder sb = new StringBuilder();
            sb.append("MERCHANTID=").append(CCBConstants.MERCHANTID).append("&POSID=").append(CCBConstants.POSID)
                    .append("&BRANCHID=").append(CCBConstants.BRANCHID).append("&ORDERID=")
                    .append(payRequestInfo.getOrderNo()).append("&PAYMENT=").append(orderPrice.toString())
                    .append("&CURCODE=").append(CCBConstants.CURCODE).append("&TXCODE=").append(CCBConstants.TXCODE)
                    .append("&REMARK1=").append(CCBConstants.REMARK1).append("&REMARK2=").append(CCBConstants.REMARK2)
                    .append("&TYPE=").append(CCBConstants.TYPE).append("&PUB=").append(CCBConstants.PUB).append("&GATEWAY=")
                    .append(CCBConstants.GATEWAY).append("&CLIENTIP=").append(payRequestInfo.getSpbillCreateIp())
                    .append("&REGINFO=").append(CCBConstants.REGINFO).append("&PROINFO=").append(CCBConstants.PROINFO)
                    .append("&REFERER=").append(CCBConstants.REFERER).append("&TRADE_TYPE=")
                    .append(payRequestInfo.getTradeType()).append("&SUB_APPID=").append(payRequestInfo.getAppId())
                    .append("&SUB_OPENID=").append(payRequestInfo.getOpenId());
            String sign = MD5Utils.MD5Encode(sb.toString(), "UTF-8").toLowerCase();
            map.put("MAC", sign);
            String data = null;
            CCBPayResult cCBPayResult = null;
            try {
                data = HttpClientUtil.doPost(CCBConstants.CCB_CREATE_ORDER_URL, map);
                JSONObject parseObject = JSON.parseObject(data);
                LOGGER.info("cCBPayment data  [{}]", data);
                cCBPayResult = createOrderUrl(parseObject.getString("PAYURL"));
                if (!"true".equals(cCBPayResult.getSuccess()) || !"000000".equals(cCBPayResult.getErrcode())) {
                    throw new BizException(ErrorCode.BIZ_EXCEPTION.getErrcode(), "抱歉调用建行支付接口失败");
                }
            } catch (Exception e) {
                LOGGER.info("cCBPayment Error [{}],{}", data, e);
                throw new BizException(ErrorCode.BIZ_EXCEPTION.getErrcode(), e.getMessage());
            }
            return cCBPayResult;
        }
    
        public CCBPayResult createOrderUrl(String payUrl) {
            CCBPayResult ccbPayResult = new CCBPayResult();
            String data = null;
            try {
                data = HttpClientUtil.doPost(payUrl, null);
                JSONObject parseObject = JSON.parseObject(data);
                ccbPayResult.setSuccess(parseObject.getString("SUCCESS"));
                ccbPayResult.setErrcode(parseObject.getString("ERRCODE"));
                ccbPayResult.setErrmsg(parseObject.getString("ERRMSG"));
                ccbPayResult.setTxcode(parseObject.getString("TXCODE"));
                ccbPayResult.setAppId(parseObject.getString("appId"));
                ccbPayResult.setTimeStamp(parseObject.getString("timeStamp"));
                ccbPayResult.setNonceStr(parseObject.getString("nonceStr"));
                ccbPayResult.setPackageValue(parseObject.getString("package"));
                ccbPayResult.setSignType(parseObject.getString("signType"));
                ccbPayResult.setPaySign(parseObject.getString("paySign"));
                ccbPayResult.setPartnerid(parseObject.getString("partnerid"));
                ccbPayResult.setPrepayid(parseObject.getString("prepayid"));
                ccbPayResult.setMwebUrl(parseObject.getString("mweb_url"));
                LOGGER.info("createOrderUrl data [{}]", data);
            } catch (Exception e) {
                LOGGER.info("createOrderUrl Error [{}],{}", data, e);
                e.printStackTrace();
            }
            return ccbPayResult;
        }
    
        
    
    }

    封装请求的基本参数PayRequestInfo

    public class PayRequestInfo implements java.io.Serializable {
        private static final long serialVersionUID = -1249414762571339701L;
        /**
         * 订单号
         */
        private String orderNo;
        /**
         * 商品描述
         */
        private String body;
        /**
         * 支付类型 1:为原生态微信支付渠道 2:建议支付渠道
         */
        private Integer payType;
        /**
         * 支付金额,单位统一为分
         */
        private Integer orderPrice;
        /**
         * 公众号/小程序 用户唯一标识openId
         */
        private String openId;
        /**
         * ip
         */
        private String spbillCreateIp;
        /**
         * 微信支付时回调地址
         */
        private String notifyUrl;
        /**
         * 公众号/小程序的appid
         */
        private String appId;
        /**
         * 交易类型
         */
        private String tradeType;
        public String getOrderNo() {
            return orderNo;
        }
        public void setOrderNo(String orderNo) {
            this.orderNo = orderNo;
        }
        public String getBody() {
            return body;
        }
        public void setBody(String body) {
            this.body = body;
        }
        public Integer getPayType() {
            return payType;
        }
        public void setPayType(Integer payType) {
            this.payType = payType;
        }
        public Integer getOrderPrice() {
            return orderPrice;
        }
        public void setOrderPrice(Integer orderPrice) {
            this.orderPrice = orderPrice;
        }
        public String getOpenId() {
            return openId;
        }
        public void setOpenId(String openId) {
            this.openId = openId;
        }
        public String getSpbillCreateIp() {
            return spbillCreateIp;
        }
        public void setSpbillCreateIp(String spbillCreateIp) {
            this.spbillCreateIp = spbillCreateIp;
        }
        public String getNotifyUrl() {
            return notifyUrl;
        }
        public void setNotifyUrl(String notifyUrl) {
            this.notifyUrl = notifyUrl;
        }
        public String getTradeType() {
            return tradeType;
        }
        public void setTradeType(String tradeType) {
            this.tradeType = tradeType;
        }
        public String getAppId() {
            return appId;
        }
        public void setAppId(String appId) {
            this.appId = appId;
        }
    }

    请求建行支付结构返回的结果集

    public class CCBPayResult extends PayResult implements Serializable{
        private static final long serialVersionUID = 8387757441935173456L;
        /**
         * 返回状态码 
         */
        private String success;
        /**
         * 错误码 
         * 000000 表示交易成功,非 000000 表示交易失败
         */
        private String errcode;
        /**
         * 错误信
         */
        private String errmsg;
        /**
         * 交易码 
         */
        private String txcode;
        /**
         * 微信分配的 APPID 
         */
        private String appId;
        /**
         * 时间戳 
         */
        private String timeStamp;
        /**
         * 随机串 
         */
        private String nonceStr;
        /**
         * 数据包
         */
        private String packageValue;
        /**
         * 签名方式 
         */
        private String signType;
        /**
         * 签名数据 
         */
        private String paySign;
        /**
         * 子商户的商户号 
         */
        private String partnerid;
        /**
         * 预支付交易会话 ID 
         */
        private String prepayid;
        /**
         * 微信H5支付中间页面 URL 
         */
        private String mwebUrl;
        public String getSuccess() {
            return success;
        }
        public void setSuccess(String success) {
            this.success = success;
        }
        public String getErrcode() {
            return errcode;
        }
        public void setErrcode(String errcode) {
            this.errcode = errcode;
        }
        public String getErrmsg() {
            return errmsg;
        }
        public void setErrmsg(String errmsg) {
            this.errmsg = errmsg;
        }
        public String getTxcode() {
            return txcode;
        }
        public void setTxcode(String txcode) {
            this.txcode = txcode;
        }
        public String getAppId() {
            return appId;
        }
        public void setAppId(String appId) {
            this.appId = appId;
        }
        public String getTimeStamp() {
            return timeStamp;
        }
        public void setTimeStamp(String timeStamp) {
            this.timeStamp = timeStamp;
        }
        public String getNonceStr() {
            return nonceStr;
        }
        public void setNonceStr(String nonceStr) {
            this.nonceStr = nonceStr;
        }
        public String getPackageValue() {
            return packageValue;
        }
        public void setPackageValue(String packageValue) {
            this.packageValue = packageValue;
        }
        public String getSignType() {
            return signType;
        }
        public void setSignType(String signType) {
            this.signType = signType;
        }
        public String getPaySign() {
            return paySign;
        }
        public void setPaySign(String paySign) {
            this.paySign = paySign;
        }
        public String getPartnerid() {
            return partnerid;
        }
        public void setPartnerid(String partnerid) {
            this.partnerid = partnerid;
        }
        public String getPrepayid() {
            return prepayid;
        }
        public void setPrepayid(String prepayid) {
            this.prepayid = prepayid;
        }
        public String getMwebUrl() {
            return mwebUrl;
        }
        public void setMwebUrl(String mwebUrl) {
            this.mwebUrl = mwebUrl;
        }
        
    }

    HttpClientUtil

    public class HttpClientUtil {
        private static HttpClient httpClient = new DefaultHttpClient();
    
        /**
         * 发送 get 请求
         * 
         * @param url
         * @return
         */
        public static String get(String url) {
            String body = null;
            try {
                // get 请求
                HttpGet httpGet = new HttpGet(url);
                // 发送请求
                HttpResponse httpresponse = httpClient.execute(httpGet);
                // 获取返回数据
                HttpEntity entity = httpresponse.getEntity();
                body = EntityUtils.toString(entity, "UTF-8");
                if (entity != null) {
                    entity.consumeContent();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return body;
        }
    
        /**
         * 发送get 请求
         * 
         * @param url
         * @param params
         * @return
         */
        public static String get(String url, List<NameValuePair> params) {
            String body = null;
            try {
                HttpGet httpGet = new HttpGet(url);
                String data = EntityUtils.toString(new UrlEncodedFormEntity(params));
                httpGet.setURI(new URI(httpGet.getURI().toString() + "?" + data));
                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity entity = httpResponse.getEntity();
                body = EntityUtils.toString(entity, "UTF-8");
                if (entity != null) {
                    entity.consumeContent();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return body;
        }
    
        /**
         * post
         * 
         * @param url
         * @param params
         * @return
         */
        public static String post(String url, List<NameValuePair> params) {
            String body = null;
            try {
                if (httpClient == null) {
                    httpClient = new DefaultHttpClient();
                }
                HttpPost httpPost = new HttpPost(url);
                httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
                HttpResponse httpResponse = httpClient.execute(httpPost);
                HttpEntity entity = httpResponse.getEntity();
                body = EntityUtils.toString(entity, "UTF-8");
                if (entity != null) {
                    entity.consumeContent();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return body;
        }
    
        /**
         * 以 closeableHttpClient方式 发送get 请求
         * 
         * @param uri
         * @return
         */
        public static String getCloseableHttpResponse(String url) {
            String body = null;
            try {
                CloseableHttpClient client = HttpClients.custom().build();
                HttpGet httpGet = new HttpGet(url);
                CloseableHttpResponse chr = client.execute(httpGet);
                String data = EntityUtils.toString(chr.getEntity(), "UTF-8");
                JSONObject json = JSON.parseObject(data);
                body = json.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return body;
        }
    
        /**
         * post 请求
         * @param url
         * @param param
         * @return
         */
        public static String doPost(String url, Map<String, String> param) {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            CloseableHttpResponse response = null;
            String resultString = "";
            try {
                HttpPost httpPost = new HttpPost(url);
                if (param != null) {
                    List<NameValuePair> paramList = new ArrayList<>();
                    for (String key : param.keySet()) {
                        paramList.add(new BasicNameValuePair(key, param.get(key)));
                    }
                    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList, "utf-8");
                    httpPost.setEntity(entity);
                }
                response = httpClient.execute(httpPost);
                resultString = EntityUtils.toString(response.getEntity(), "utf-8");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return resultString;
        }
    }

    MD5Utils

    public class MD5Utils {
    
        private static String byteArrayToHexString(byte b[]) {
            StringBuffer resultSb = new StringBuffer();
            for (int i = 0; i < b.length; i++)
                resultSb.append(byteToHexString(b[i]));
    
            return resultSb.toString();
        }
    
        private static String byteToHexString(byte b) {
            int n = b;
            if (n < 0)
                n += 256;
            int d1 = n / 16;
            int d2 = n % 16;
            return hexDigits[d1] + hexDigits[d2];
        }
    
        public static String MD5Encode(String origin, String charsetname) {
            String resultString = null;
            try {
                resultString = new String(origin);
                MessageDigest md = MessageDigest.getInstance("MD5");
                if (charsetname == null || "".equals(charsetname))
                    resultString = byteArrayToHexString(md.digest(resultString
                            .getBytes()));
                else
                    resultString = byteArrayToHexString(md.digest(resultString
                            .getBytes(charsetname)));
            } catch (Exception exception) {
            }
            return resultString;
        }
        
        private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    }

    之前忘记没贴上Controller 层 现在加上

    
    

    @Autowired
    private PayApi payApi;


    /**
    * 统一添加订单 * * @param paymentOrder * @return */ @WeiXinLogin @RequestMapping("/addOrder") public ResponseModel addOrder(OrderVO orderVO) { LoginUserVO user = RequestContext.getContext().getUser(); String key = PAYMENT_ORDER_ADD_LOCK_KEY + user.getMemberId(); try { orderVO.setMemberId(user.getMemberId()); orderVO.setOrderNo(wechatOrderNo.nextId() + ""); orderVO.setPayType(PayType.CCBPAY);// 订单支付渠道为建行 if (redisLockUtil.tryLock(key, 10)) { Integer orderId = orderApi.addOrder(orderVO); return new ResponseModel(orderId); } else { return new ResponseModel(ErrorCode.BIZ_EXCEPTION.getErrcode(), "操作过于频繁", null); } } catch (BizException e) { LOGGER.error("addOrder error,{}", e); return new ResponseModel(e.getErrcode(), e.getErrm(), null); } finally { redisLockUtil.unlock(key); } } /** * 支付 * @param orderId * @param request * @return * @throws Exception */ @WeiXinLogin @RequestMapping("/prePay") public ResponseModel prePay(Integer orderId, HttpServletRequest request) throws Exception { String key = PAYMENT_ORDER_PREPAY_LOCK_KEY + orderId; try { LoginUserVO user = RequestContext.getContext().getUser(); PaymentOrderRecord orderRecord = orderApi.getOrderById(orderId); PayRequestInfo payRequestInfo = new PayRequestInfo(); payRequestInfo.setBody("xxx缴费"); payRequestInfo.setNotifyUrl(systemConfig.getPayNotifyUrl());//该回调地址只是微信支付,与建行支付没关系 如果是建行支付直接忽略这行代码 payRequestInfo.setOpenId(user.getAppOpenId()); payRequestInfo.setOrderNo(orderRecord.getOrderNo()); payRequestInfo.setOrderPrice(orderRecord.getOrderPrice()); payRequestInfo.setPayType(orderRecord.getPayType()); payRequestInfo.setSpbillCreateIp(getIpAddr(request)); payRequestInfo.setTradeType("MINIPRO"); payRequestInfo.setAppId(systemConfig.getAppletsAppId()); String randomNum = System.currentTimeMillis() + new Random().nextInt(10000) + ""; if (redisLockUtil.tryLock(key, randomNum, 5)) { PayResult payResult = payApi.pay(payRequestInfo); return new ResponseModel(payResult); } else { return new ResponseModel(ErrorCode.BIZ_EXCEPTION.getErrcode(), "操作过于频繁", null); } } catch (BizException e) { LOGGER.error("prePay error,{}", e); return new ResponseModel(e.getErrcode(), e.getErrm(), null); } finally { redisLockUtil.unlock(key); } } /** * 建行支付结果通知 * * @param request * @return */ @RequestMapping("/callBackCCB") public String callBackCCB(HttpServletRequest request) { LOGGER.info("callBackCCB start!"); try { Map<String, String> map = new HashMap<String, String>(); Enumeration<String> parameterNames = request.getParameterNames(); StringBuilder data = new StringBuilder(); while (parameterNames.hasMoreElements()) { String name = (String) parameterNames.nextElement(); String value = request.getParameter(name); map.put(name, value); data.append(name).append("=").append(value).append("&"); } LOGGER.info("callBackCCB source data :[{}]", data.toString());// 建行返回调原数据 StringBuilder sb = new StringBuilder(); sb.append("POSID=").append(map.get("POSID")).append("&BRANCHID=").append(map.get("BRANCHID")) .append("&ORDERID=").append(map.get("ORDERID")).append("&PAYMENT=").append(map.get("PAYMENT")) .append("&CURCODE=").append(map.get("CURCODE")).append("&REMARK1=").append(map.get("REMARK1")) .append("&REMARK2=").append(map.get("REMARK2")).append("&ACC_TYPE=").append(map.get("ACC_TYPE")) .append("&SUCCESS=").append(map.get("SUCCESS")).append("&TYPE=").append(map.get("TYPE")) .append("&REFERER=").append(map.get("REFERER")).append("&CLIENTIP=").append(map.get("CLIENTIP")) .append("&ACCDATE=").append(map.get("ACCDATE")); RSASig rsaSig = new RSASig(); rsaSig.setPublicKey(CCBConstants.PUBLICKEY);// 公钥 boolean flag = rsaSig.verifySigature(map.get("SIGN"), sb.toString()); LOGGER.info("callBackCCB Check :[{}]", flag); if ("Y".equals(map.get("SUCCESS")) && flag) {//表示支付成功 CallbackResult callbackResult = new CallbackResult(); callbackResult.setReturnCode("Y"); callbackResult.setReturnMsg("Ok"); callbackResult.setOrderNo(map.get("ORDERID"));// 订单号 payApi.callBack(callbackResult); } } catch (Exception e) { LOGGER.error("callBackCCB error,{}", e); } return null; }



    //PayApi 接口的实现类
    package com.qft.payment.service.pay;
    
    import java.util.Date;
    import java.util.UUID;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.qft.payment.api.order.OrderApi;
    import com.qft.payment.api.order.constant.OrderConstant;
    import com.qft.payment.api.order.constant.PayType;
    import com.qft.payment.api.order.model.NotesOrder;
    import com.qft.payment.api.order.model.PaymentOrderRecord;
    import com.qft.payment.api.pay.CCBPayApi;
    import com.qft.payment.api.pay.PayApi;
    import com.qft.payment.api.pay.WechatPayApi;
    import com.qft.payment.api.pay.model.CallbackResult;
    import com.qft.payment.api.pay.model.PayRequestInfo;
    import com.qft.payment.api.pay.model.PayResult;
    import com.qft.payment.api.pay.model.RefundInfo;
    import com.qft.payment.api.pay.model.WechatRefundResutl;
    import com.qft.payment.api.payaccount.PayAccountApi;
    import com.qft.payment.common.constant.ErrorCode;
    import com.qft.payment.common.exception.BizException;
    import com.qft.payment.common.util.SimpleRedisLockUtil;
    
    /**
     * 
     * @author ckj
     *
     */
    @Service
    public class PayServiceImpl implements PayApi {
        private static final Logger LOGGER = LoggerFactory.getLogger(PayServiceImpl.class);
        @Autowired
        private WechatPayApi wechatPayApi;
    
        @Autowired
        private CCBPayApi cCBPayApi;
        private static final String ORDER_CALLBACK_LOCK_KEY = "order:lock:callback";
        @Autowired
        private SimpleRedisLockUtil redisLockUtil;
    
        @Override
        public PayResult pay(PayRequestInfo payRequestInfo) throws BizException {
            PayResult payResult = new PayResult();
            if (payRequestInfo.getPayType() == null) {
                throw new BizException(ErrorCode.BIZ_EXCEPTION.getErrcode(), "支付类型不能为null");
            }
            try {
                if (payRequestInfo.getPayType() == PayType.WECHATPAY) {// 表示微信原生态支付渠道
                    payResult = wechatPayApi.jsApiPay(payRequestInfo);
                } else if (payRequestInfo.getPayType() == PayType.CCBPAY) {// 表示建行支付渠道
                    payResult = cCBPayApi.cCBPayment(payRequestInfo);
                }
                addNotesOrder(payRequestInfo);
            } catch (Exception e) {
                LOGGER.info("pay Error [{}],{}", payRequestInfo.getOrderNo(), e);
                throw new BizException(ErrorCode.BIZ_EXCEPTION.getErrcode(), e.getMessage());
            }
            return payResult;
        }
    }
    
    
    
     
  • 相关阅读:
    手机摇一摇代码
    ftp
    .net 设置导航的当前状态
    app 尺寸
    繁简体 互转 js
    静态页分页效果
    判断浏览器
    python列表,元组,字典和字符串之间的相互转换
    uliweb框架数据库操作
    uliweb的模版
  • 原文地址:https://www.cnblogs.com/SHMILYHP/p/11381381.html
Copyright © 2011-2022 走看看