原创 

微信免签约收款方案及源码(android+java)

分类:android    110人阅读    IT小君  2024-10-10 22:45

问题:

1、如何收款?

2、如何接收微信收款通知?

     2-1:如何知道是那个渠道的收款信息?

     2-2:如何知道是哪个收款码

3、如何保证通知完整性

方案

问题1:使用多张收款二维码,每一个订单占用一张二维码直到支付完成或者订单超时释放二维码

问题2:

      使用android AccessibilityService (无障碍服务,辅助残障人士用的自动化实现,具体详情可参考:https://blog.csdn.net/qq_24428851/article/details/141334492)

      监听微信支付页面的UI变化,获取页面UI文本信息,解析过滤出支付信息。(AccessibilityService抢红包、抢茅台都可实现)

问题2-1、2-2:

       生成微信收款码设置金额的时候可以添加“收款方备注”如图,我们可以将渠道和收款码唯一标识设置为备注

           

用户支付后微信支付可以收到带有“收款方备注”的支付信息,如下图:

然后 app 中使用AccessibilityService 无障碍服务接收AccessibilityEvent 事件,抓取UI信息,然后异步发送通知给后台支付服务,后台支付服务处理通知第三方,UI解析代码参考如下:

public List parseNodeInfo() {
        List nodes = new ArrayList<>();
        Function<AccessibilityNodeInfo, String> TxtGetter = item -> {
            if (null != item.getText()) {
                return item.getText().toString();
            }
            return "";
        };
        try {
            String title = getNodeInfo(titleId);
            if (title.contains("微信支付") || title.contains("微信收款助手")) {
                AccessibilityNodeInfo nodeInfo = getRootInActiveWindow();
                if (nodeInfo != null) {
                    List list = nodeInfo.findAccessibilityNodeInfosByViewId(contentId);
                    for (AccessibilityNodeInfo item : list) {
                        NodeInfo node = new NodeInfo();
                        List titles = item.findAccessibilityNodeInfosByViewId(subTitle);
                        List amounts = item.findAccessibilityNodeInfosByViewId(amountLabel);
                        if (titles.size() <= 0) {
                            continue;
                        }
                        if (amounts.size() <= 0) {
                            continue;
                        }
                        String subTle = TxtGetter.apply(titles.get(0));
                        String txtAmount = TxtGetter.apply(amounts.get(0));
                        if (subTle.contains("收款到账通知")) {
                            node.setName(subTle);
                            node.setAmount(new BigDecimal(txtAmount));
                            // Define the desired date format
                            @SuppressLint("SimpleDateFormat")
                            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            // Format the date and return the string
                            node.setTime(dateFormat.format(new Date()));
                            List left = item.findAccessibilityNodeInfosByViewId(leftInfo);
                            List right = item.findAccessibilityNodeInfosByViewId(rightInfo);
                            for (int i = 0; i < left.size(); i++) {
                                AccessibilityNodeInfo subItem = left.get(i);
                                String label = TxtGetter.apply(subItem);
                                String val = TxtGetter.apply(right.get(i));
                                if (label.contains("收款方备注")) {
                                    node.setSellerRemark(val);
                                    if (null != val && val.startsWith("ICode联盟收款")) {
                                        node.setIden(val.replace("ICode联盟收款-", ""));
                                    }
                                    continue;
                                }
                                if (label.contains("付款方备注")) {
                                    node.setBuyerRemark(val);
                                }
                                if (label.contains("汇总")) {
                                    node.setSumInfo(val);
                                }
                                if (label.contains("备注")) {
                                    node.setRemark(val);
                                }
                            }
                        }

                        nodes.add(node);
                    }
                }
            }
        } catch (Exception ex) {
            Log.e("exception", "getNodeInfo: ", ex);
        }
        return nodes;
    }

具体源代码可参考文末下载链接。

问题3

1、手机端可以保存一份近期的支付通知数据在sqllite 数据库,做一个列表展示加上重新推送后台支付服务的按钮

3、后端服务定时轮询关闭超期订单释放收款码

 

android 端app源代码下载地址:待更

 

 

 

支付宝打赏 微信打赏

如果文章对你有帮助,欢迎点击上方按钮打赏作者

 工具推荐 更多»