问题:
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源代码下载地址:待更