| | |
| | | |
| | | public enum Outcome { SUCCEEDED, PROCESSING, FAILED } |
| | | |
| | | /** 通道说「已经没有待确认金额」:这笔延迟交易此前已经确认过,属于幂等成功。 */ |
| | | private static final String NOTHING_LEFT_TO_CONFIRM = "23000003"; |
| | | |
| | | public boolean settled() { |
| | | return outcome != Outcome.PROCESSING; |
| | | } |
| | |
| | | String unconfirmed = HuifuPayload.value(data, "unconfirm_amt", "unconfirmAmt"); |
| | | String confirmed = HuifuPayload.value(data, "confirmed_amt", "confirmedAmt"); |
| | | String providerNo = HuifuPayload.value(data, "hf_seq_id", "org_hf_seq_id", "hfSeqId", "orgHfSeqId"); |
| | | return new HuifuDelayConfirmation(classify(status, code), code, message, unconfirmed, confirmed, providerNo); |
| | | return new HuifuDelayConfirmation( |
| | | classify(status, code, message), code, message, unconfirmed, confirmed, providerNo); |
| | | } |
| | | |
| | | /** |
| | | * 交易确认的同步响应只有 {@code resp_code} 和金额字段,没有交易状态;受理成功码是 |
| | | * {@code 00000000},{@code 00000100} 表示还在处理中。明确的失败码按失败处理。 |
| | | * {@code 00000000},{@code 00000100} 表示还在处理中。 |
| | | * |
| | | * <p>{@code 23000003 已无未确认金额} 说明这笔延迟交易此前已经确认过(重新确认不会重复分账), |
| | | * 必须按成功处理:否则补偿任务会一直认为没确认,每隔几分钟无意义地打一次通道。 |
| | | * 这个判断放在交易状态之前——通道在「没有待确认金额」时同时会给 {@code trans_stat=F}, |
| | | * 先看状态就会把这个幂等成功误判成失败。 |
| | | */ |
| | | private static Outcome classify(String status, String code) { |
| | | boolean accepted = HuifuPayload.successCode(code); |
| | | private static Outcome classify(String status, String code, String message) { |
| | | String normalizedCode = code == null ? "" : code.trim(); |
| | | if (NOTHING_LEFT_TO_CONFIRM.equals(normalizedCode)) return Outcome.SUCCEEDED; |
| | | if (HuifuPayload.successCode(normalizedCode)) return Outcome.SUCCEEDED; |
| | | if (HuifuPayload.status(status) == HuifuPayload.TransStatus.FAILED) return Outcome.FAILED; |
| | | if (accepted) return Outcome.SUCCEEDED; |
| | | if ("00000100".equals(code == null ? "" : code.trim())) return Outcome.PROCESSING; |
| | | return code == null || code.isBlank() ? Outcome.PROCESSING : Outcome.FAILED; |
| | | if ("00000100".equals(normalizedCode)) return Outcome.PROCESSING; |
| | | return normalizedCode.isBlank() ? Outcome.PROCESSING : Outcome.FAILED; |
| | | } |
| | | |
| | | /** 供日志与故障定位使用的一句话结论。 */ |