E企盈营销工具技术服务商 热线:4006-838-530

微信App支付、小程序支付、H5支付踩坑记

E企盈直播平台营销卖货系统

首先,强调下其实不管是什么支付。第一步基本上都是调用统一下单接口,然后二次签名。调起支付。下面就一一说下我踩的坑1、App支付、小程序支付、H5支付统一支付签名参数问题。这是我做完小程序支付 ,做App支付时。想重用代码发生的坑。话不多说,直接上图小程序参数‘’App参数发现问题了吗?没错,同样的接口,居然参数大小写不一致。。。2、金额单位问题金额单位为分,我们系统一般是元,这需要转换。并且在回调接口中也需要注意。特别注意:金额是整数,没有小数,没有小数,没有小数。重要事情说三遍。3、appid、mch_id(商户id)、秘钥、商户key区别以及签名问题首先小程序的appid和App的appid不一致。商户id没啥说的,商户key是在商户平台设置的。这就是调起支付中二次签名的key。具体设置路径:最后,签名时是有顺序要求的。具体看文档具体代码,可以下载官方支付sdk。里面基本以及把所用的的工具类都写好了。只需要修改下就可以。大致结构:qizhong 其中WXPay是核心类,WXPayConfig是配置类。如果想封装统一下单和二次签名以及支付回调,需要对配置类做出修改。我贴下我的代码import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Configuration;import java.io.ByteArrayInputStream;import java.io.InputStream;@Configurationpublic class WXPayConfigImpl extends WXPayConfig {private byte[] certData;    private static WXPayConfigImpl INSTANCE;    @Value(“${wx.appId}”)    private String appId;    @Value(“${wx.mchId}”)    private String mchId;    @Value(“${wx.key}”)    private String key;    @Value(“${wx.notifyUrl}”)    private String notifyUrl;    @Value(“${wx.timeOut}”)    private Integer timeOut;    @Value(“${wx.appTimeOut}”)    private Integer appTimeOut;    @Value(“${wx.bodyName}”)    private String bodyName;    @Value(“${wx.tradeType}”)    private String tradeType;    public String getAppId() {        return appId;    }    public void setAppId(String appId) {        this.appId = appId;    }    public String getMchId() {        return mchId;    }    public void setMchId(String mchId) {        this.mchId = mchId;    }    public void setKey(String key) {        this.key = key;    }    public String getNotifyUrl() {        return notifyUrl;    }    public void setNotifyUrl(String notifyUrl) {        this.notifyUrl = notifyUrl;    }    public Integer getTimeOut() {        return timeOut;    }    public void setTimeOut(Integer timeOut) {        this.timeOut = timeOut;    }    public Integer getAppTimeOut() {        return appTimeOut;    }    public void setAppTimeOut(Integer appTimeOut) {        this.appTimeOut = appTimeOut;    }    public String getBodyName() {        return bodyName;    }    public void setBodyName(String bodyName) {        this.bodyName = bodyName;    }    public void setTradeType(String tradeType) {        this.tradeType = tradeType;    }           public static WXPayConfigImpl getInstance() throws Exception{        if (INSTANCE == null) {            synchronized (WXPayConfigImpl.class) {                if (INSTANCE == null) {                    INSTANCE = new WXPayConfigImpl();                }            }        }        return INSTANCE;    }    @Override    public String getAppID() {        return appId;    }    @Override    public String getMchID() {        return mchId;    }    @Override    public String getKey() {        return key;    }    public String getNotifUrl() {        return notifyUrl;    }    /**      * @Description  交易类型 NATIVE: 适用于实体店 JSAPI 移动端支付     * @param     * @date 2019/9/11    */     public String getTradeType() {        return tradeType;    }    @Override    public InputStream getCertStream() {        ByteArrayInputStream certBis;        certBis = new ByteArrayInputStream(this.certData);        return certBis;    }    @Override    public int getHttpConnectTimeoutMs() {        return 2000;    }    @Override    public int getHttpReadTimeoutMs() {        return 10000;    }    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 String getSpbillCreateIp() {        return “1.192.218.185”;    }@Overridepublic IWXPayDomain getWXPayDomain() {return WXPayDomainSimpleImpl.instance();}}二次签名   //统一下单public BoyMap  createOrder(HttpServletRequest request, Order order,WXPayConfigImpl config) {        log.info(“【用户下单模块】–开始”);        try {            MapString,String paramMap = new HashMap();                          WXPay wxPay = new WXPay(config);                //拼装参数                MapString,String data = generateParam(order,request,config);                log.info(“【用户下单模块】 — 调用微信统一下参数为:” + JSONObject.toJSONString(data));                MapString, String resp = wxPay.unifiedOrder(data);                log.info(“【用户下单模块】 — 调用微信统一下单返回结果为:” + JSONObject.toJSONString(resp));                if(resp != null){                    String returnCode = resp.get(“return_code”);                    //成功                    if(WXPayConstants.SUCCESS.equalsIgnoreCase(returnCode)){                        //保存订单,自己的业务                        saveWXPayInfo(order,data.get(“out_trade_no”),config);                        paramMap.put(“prepayId”,resp.get(“prepay_id”));                    }                }else {                    log.info(“【用户下单模块】–调用微信支付接口异常”);                    return BoyMap .error(“微信支付异常”);                }                        log.info(“【用户下单模块】– 调用微信统一下单成功,返回前台数据为: ” + JSONObject.toJSONString(paramMap));            return BoyMap .ok().put(“paramMap”,paramMap);        } catch (Exception e) {            log.error(“【用户下单模块】–异常:” + e.getMessage());            e.printStackTrace();            return BoyMap .error(“系统异常”);        }    }//封装参数@Override    public MapString, String generateParam(Order order,HttpServletRequest request,WXPayConfigImpl config){        MapString, String data = new HashMapString, String();        data.put(“nonce_str”, WXPayUtil.generateNonceStr());        data.put(“body”, config.getBodyName());        //商户订单号        //生成订单编号        if(StringUtils.isNotBlank(order.getOrderNo())){            data.put(“out_trade_no”, order.getOrderNo());        }else {            data.put(“out_trade_no”, SgenerateOrderNo(config));        }        //签名类型        data.put(“sign_type”, “MD5”);        //标价币种        if(ycejWxPayOrder.getCurrencyType() == null){            data.put(“fee_type”, “CNY”);        }        //终端IP        data.put(“spbill_create_ip”, IPUtils.getIpaddr(request));        //通知地址 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。        data.put(“notify_url”,config.getNotifUrl());        // 交易类型        data.put(“trade_type”, config.getTradeType());        BigDecimal amount = new BigDecimal(0.0);       //订单金额        amount = order.getAmout().multiply(new BigDecimal(100));               String amountMoney = String.valueOf(amount);         //金额必须为整数        if(amountMoney.contains(“.”)){            amountMoney = amountMoney.substring(0,amountMoney.indexOf(“.”));        }        //标价金额        data.put(“total_fee”, (amount.compareTo(BigDecimal.ZERO) == 0)? “0”:amountMoney);        return data;    }//二次签名@Override    public BoyMap generateSignature(String prepayId,WXPayConfigImpl config) {        log.info(“【微信支付二次签名模块】–开始”);        MapString,String paramMap = null;        MapString,String signMap =null;        try {            paramMap = new HashMap();            signMap = new HashMap();            String nonceStr = UUIDUtil.getUUID();            String timeStamp = StringTools.stringOf(System.currentTimeMillis()/1000);            //H5 支付跳转地址            if(“APP”.equalsIgnoreCase(config.getTradeType())){                //再次签名                signMap.put(“appid”,config.getAppID());                signMap.put(“noncestr”,nonceStr);                signMap.put(“package”,”Sign=WXPay”);                signMap.put(“partnerid”,config.getMchID());                signMap.put(“prepayid”,prepayId);                signMap.put(“timestamp”,timeStamp);            }else if(“JSAPI”.equalsIgnoreCase(config.getTradeType())){                signMap.put(“appId”,config.getAppID());                signMap.put(“timeStamp”,timeStamp);                signMap.put(“nonceStr”,nonceStr);                signMap.put(“package”,”prepay_id=”+prepayId);                signMap.put(“signType”,”MD5″);            }            //二次组装签名            String sign = WXPayUtil.generateSignature(signMap,config.getKey(), “MD5”);            if(sign != null){                log.info(“【微信支付二次签名模块】–成功,签名为==:” + sign);                if(“APP”.equalsIgnoreCase(config.getTradeType())){                    paramMap.put(“appid”,config.getAppID());                    paramMap.put(“noncestr”,nonceStr);                    paramMap.put(“package”,”Sign=WXPay”);                    paramMap.put(“partnerid”,config.getMchID());                    paramMap.put(“timestamp”,timeStamp);                    paramMap.put(“sign”,sign);                    paramMap.put(“prepayid”,prepayId);                }else if(“JSAPI”.equalsIgnoreCase(config.getTradeType())){                    paramMap.put(“nonceStr”,nonceStr);                    paramMap.put(“sign”,sign);                    paramMap.put(“timeStamp”,timeStamp);                }                return R.ok().put(“paramMap”,paramMap);            }else {                log.info(“【微信支付二次签名模块】–失败”);                return BoyMap .error(“签名失败!”);            }        } catch (Exception e) {            log.info(“【微信支付二次签名模块】–异常”);            e.printStackTrace();        }        return BoyMap .error(“签名失败!”);    }

赞(0) 打赏
未经允许不得转载:E企盈小程序开发-热线:4006-838-530 » 微信App支付、小程序支付、H5支付踩坑记
分享到: 更多 (0)
E企盈小程序直播营销卖货系统
E企盈直播平台营销卖货系统

评论 抢沙发

E企盈小程序开发

联系我们联系我们

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏