微信下单、支付流程和注意事项

news/2024/12/23 6:33:18/

目录

1.官方微信支付流程

2.平台微信下单支付流程

3.关键代码

5.注意事项


1.官方微信支付流程

2.平台微信下单支付流程


3.关键代码

生成微信签名代码

    /*** 生成签名* @return 签名*/public static String getSign(Map<String,?> map){List<String> list = new ArrayList<>();Map<String,Object> map2 =new TreeMap<>(map);for(Map.Entry<String,Object> entry:map2.entrySet()){if(entry.getValue()!=""){list.add(entry.getKey() + "=" + entry.getValue() + "&");}}int size = list.size();String [] arrayToSort = list.toArray(new String[size]);Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);StringBuilder sb = new StringBuilder();for(int i = 0; i < size; i ++) {sb.append(arrayToSort[i]);}String result = sb.toString();result += "key=" + WeixinpayConfig.KEY;//此处待修改result = DigestUtils.md5Hex(result).toUpperCase();return result;}
构造微信统一下单参数
	/*** <一句话功能简述> 构造微信统一下单参数* <功能详细描述>* author: zhanggj* 创建时间:  2018年12月18日* @param onlinePayRecord 平台在线支付记录* @param appid 微信appId* @param tradeType 支付类型 取值如下:JSAPI(小程序,二维码),NATIVE,APP,MWEB (H5支付)* @param sceneInfo H5支付需要* @param openId 小程序支付,用户openid*/private String struckUnifiedOrderParam(OnlinePayRecord onlinePayRecord, String appid,String tradeType, String sceneInfo, String openId){HashMap<String, Object> parameterMap = new HashMap<>();parameterMap.put("appid", appid);parameterMap.put("mch_id", WeixinpayConfig.MCH_ID);// 微信支付分配的商户号parameterMap.put("nonce_str", RandomStringUtils.randomAlphabetic(30));// 获取随机字符串parameterMap.put("body", onlinePayRecord.getItemNames());// 商品或支付单简要描述parameterMap.put("out_trade_no", onlinePayRecord.getRecordId());// 户系统内部的订单号,32个字符内、可包含字母// 订单总金额 单位分BigDecimal payAmount = onlinePayRecord.getTotalAmount().multiply(new BigDecimal(100));parameterMap.put("total_fee", payAmount.intValue());//订单总金额 单位分parameterMap.put("spbill_create_ip", onlinePayRecord.getRemarks());// APP和网页支付提交用户端iplong dateLong = System.currentTimeMillis();parameterMap.put("time_start", DateUtils.getStrDate(new Date(dateLong),"yyyyMMddHHmmss"));//订单生成时间 (非必填)dateLong += 10 * 60 * 1000; // 10分钟parameterMap.put("time_expire", DateUtils.getStrDate(new Date(dateLong), "yyyyMMddHHmmss"));//订单失效时间,必须大于5分钟(非必填)parameterMap.put("notify_url", baseNotifyUrl + WeixinpayConfig.NOTIFY_URL);// 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。parameterMap.put("trade_type", tradeType); //支付类型 取值如下:JSAPI,NATIVE,APP,MWEB// H5 支付需要if (StringUtils.isNotBlank(sceneInfo)) {parameterMap.put("scene_info", sceneInfo);//支付场景}if (StringUtils.isNotBlank(openId)) {parameterMap.put("openid", openId);// 获取appid参数  小程序ID}parameterMap.put("sign", WeixinpayConfig.getSign(parameterMap)); // 获取签名return XmlUtil.getXML(parameterMap);}

   jsapi支付

	/*** <一句话功能简述> JSAPI支付* <功能详细描述>* 创建时间:  2018年12月18日* @param onlinePayRecord 平台在线支付记录* @param openId 微信openId* @return 前端所需微信带签名的支付信息*/public String wxJSAPIPay(OnlinePayRecord onlinePayRecord, String openId, int wxType){// 构造统一下单参数String xmlParam = struckUnifiedOrderParam(onlinePayRecord, WeixinpayConfig.getAppId(wxType),WeixinpayConfig.WX_UNIFIEDORDER_TRADETYPE_JSAPI, null, openId);// 请求微信下单接口,创建微信订单Map<String, Object> rtnMap = unifiedOrder(xmlParam);// 与app支付不同,参数使用驼峰SortedMap<String, Object> parameterMap2 = new TreeMap<>();parameterMap2.put("appId", WeixinpayConfig.getAppId(wxType));parameterMap2.put("package", "prepay_id=" + rtnMap.get("prepay_id")); // 预付单标识parameterMap2.put("nonceStr", RandomStringUtils.randomAlphabetic(30));// 本来生成的时间戳是13位,但是ios必须是10位,所以截取了一下parameterMap2.put("timeStamp", Long.parseLong(String.valueOf(System.currentTimeMillis()).toString().substring(0,10)));parameterMap2.put("signType", "MD5");parameterMap2.put("sign", WeixinpayConfig.getSign(parameterMap2));return HttpUtils.showSuccess(parameterMap2);}

 接收到微信通知后将微信xml字符串转换为Map对象

    /*** 将微信xml字符串转换为Map对象*/public static Map<String,Object> getMapFromXML(String xmlString) {// 这里用Dom的方式解析回包的最主要目的是防止API新增回包字段DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();InputStream is = getStringStream(xmlString);Map<String, Object> map = new HashMap<>();try {DocumentBuilder builder = factory.newDocumentBuilder();Document document = builder.parse(is);// 获取到document里面的全部结点NodeList allNodes = document.getFirstChild().getChildNodes();Node node;int i=0;while (i < allNodes.getLength()) {node = allNodes.item(i);if(node instanceof Element){map.put(node.getNodeName(),node.getTextContent());}i++;}} catch (Exception e) {throw new RuntimeException(e);} finally {try {is.close();} catch (IOException e) {throw new RuntimeException(e);}}return map;}public static InputStream getStringStream(String sInputString) {ByteArrayInputStream tInputStringStream = null;if (sInputString != null && !sInputString.trim().equals("")) {tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());}return tInputStringStream;}

微信签名校验

	/*** <一句话功能简述> 微信签名校验* 创建时间:  2017年9月21日*/public boolean verifyWeixinNotify(Map<String, Object> map) {Map<String, Object> parameterMap = new TreeMap<>();String sign = (String) map.get("sign");for (String keyValue : map.keySet()) {if(!keyValue.equals("sign")){parameterMap.put(keyValue, map.get(keyValue));}}String createSign = WeixinpayConfig.getSign(parameterMap);if(createSign.equals(sign)){return true;}else{return false;}}

5.注意事项

1.下单时要记录当前所有收货信息,不要只关联收货地址ID,收货地址后续可能会变。

2.设定合理的超期时间,提前创建付款记录,不然支付超期不好处理。   

3.下单时最好提前让前端传递当前订单的推荐人是谁,这是很有必要的。

4.注意提前商定好订单确认支付页面支付金额信息与实际下单时的关系,有可能前端下单时的金额和后端处理时的金额不一致;

5.下单时前端提前根据不同卖家,划分不同订单。

6.注意现金券、运费劵抵扣,按比例无法全部平等分配的问题。

7.注意下单和完成支付时,有些低优先级事项的处理,尽量通过消息或异步线程的方式去完成,不要占用太多主事项的时间(特别注意完成支付后的处理逻辑,不要由于代码而导致出现支付超期的情况)。

8.微信统一下单时所要求的ip地址,长度不要超过限制。

9.注意处理好微信code、微信openId、平台用户ID的关系,同时注意前端缓存的微信code,不要在分享的时候带给别人,导致登录到别人的平台账号上;同时微信code不是全局唯一的,只有openId是唯一的。

10.微信支持多个订单合并付款。

11.支付时需考虑分布式扩展(支付ID不要只存储在本地节点)、外网链接的问题(不要在非外网节点上进行微信预下单,导致失败)。

12.注意微信预下单名称不要超过限制(特别是合并订单支付时)。

13.注意微信下单时间戳timeStamp在不同平台上不同,IOS上必须是10位,正常是13位。

14.注意订单总金额单位为分。

15.接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。


http://www.ppmy.cn/news/896737.html

相关文章

微信公众号-被动回复消息(文本回复)

首先要拼接对应的格式模板 $this->textTpl "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]><…

教你凭单号查询跟踪包裹物流

在发出货物包裹后&#xff0c;如何跟踪物流呢&#xff1f;一般发出的包裹都会有单号。今天就教大家批量查询单号物流信息。跟踪包裹。一起来看查询的步骤。 查询前先在电脑上下载安装一个【快递批量查询高手】&#xff0c;这个可以批量查询。软件安全&#xff0c;绿色可以放心…

微信支付:商户订单号重复

调微信同一下单接口&#xff0c;返回值中有 <result_code><![CDATA[FAIL]]></result_code> <err_code><![CDATA[OUT_TRADE_NO_USED]]></err_code> <err_code_des><![CDATA[商户订单号重复]]></err_code_des> 原因是&a…

怎么查微信公众号服务器,微信公众号查询数据库,微信公众号数据库怎么查询?...

微信公众号查询数据库&#xff0c;微信公众号数据库怎么查询?以下是小编整理的微信公众号怎么查询数据库的内容。有兴趣的朋友可以往下看看。希望以下的的内容能对您有帮助。 1、 启用消息接口登陆微信公众平台&#xff0c; 选择&#xff1a;高级功能&#xff0c;可以看到页面…

NC65 报销单使用银企直联网银支付后,银行的电子回执单的收款人开户行跟报销单的收款对象的开户行不一致

NC65 报销单使用银企直联网银支付后&#xff0c;银行的电子回执单的收款人开户行跟报销单的收款对象的开户行不一致&#xff0c;如下图&#xff1a; 解决方案&#xff1a;检查供应商的银行账户对应的联行号是否跟开户行对应。如果不对应&#xff0c;则需要修改为对应的。 如上述…

微信官方表单验证及提交

<view class"page"><mp-toptips msg"{{error}}" type"error" show"{{error}}"></mp-toptips><mp-form-page title"表单结构" subtitle"展示表单页面。"><mp-form id"form" …

微信支付订单、退款订单、转款订单的查询

payment 项目2.0版本 微信并未提供一个统一的查询接口。对应每种查询均需要不同的api。为了便于大家在项目中使用,忽略细节。对以上三种进行了封装。通过工厂的方式降低调用成本。 $wxconfig = [app_id => wxxxx, // 公众账号IDmch_id => xxxx,// 商户idmd5_key…

微信公众号之微信退款

一、前言 这次的项目主要是关于微信公众号的一个开发,本人这次分配的模块是后台微信公众号的支付和退款,第一次接触微信公众的项目刚开始一脸懵逼,开发过程中遇到各种坑,所以想自己写一篇详细的关于微信公众号的开发,希望能对小伙伴们有所帮助! 二、微信申请退款接口 微…