| | |
| | | |
| | | service.adopt(fixture.merchantId(), huifuId, APPLY_NO, true); |
| | | |
| | | verify(gateway).queryApplication(eq(huifuId), eq(APPLY_NO)); |
| | | // 两次:一次是建记录前的配对核验,一次是进度刷新本身——两处都只拿这个通道申请单号定位。 |
| | | verify(gateway, times(2)).queryApplication(eq(huifuId), eq(APPLY_NO)); |
| | | assertThat(adoptedApplicationId(fixture.merchantId(), huifuId)).isNotNull(); |
| | | } |
| | | |
| | |
| | | Fixture fixture = merchantFixture("A甲乙丙丁戊己"); |
| | | stubConvergedChannel(huifuId, "622200001234", "external-card-token", "上海汇付支付服务有限公司", "汇付支付"); |
| | | |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId); |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId, APPLY_NO); |
| | | |
| | | assertThat(String.valueOf(preview.get("nameWarning"))).contains("没有任何相同字符"); |
| | | assertThat(preview).containsEntry("channelMerchantName", "上海汇付支付服务有限公司"); |
| | |
| | | service.adopt(first.merchantId(), huifuId, APPLY_NO, true); |
| | | // 门店名与商家名一样时不重复印一遍——多数门店就是这样,列表里不该出现「某某商户(某某商户)」。 |
| | | jdbc.update("update merchant_store set store_name = ? where id = ?", first.key(), first.storeId()); |
| | | Map<String, Object> preview = service.preview(second.merchantId(), huifuId); |
| | | Map<String, Object> preview = service.preview(second.merchantId(), huifuId, APPLY_NO); |
| | | |
| | | assertThat(preview.get("boundMerchants")) |
| | | .asInstanceOf(org.assertj.core.api.InstanceOfAssertFactories.list(String.class)) |
| | |
| | | assertThat(jdbc.queryForObject("select count(*) from merchant_bank_card where merchant_id = ?", |
| | | Integer.class, fixture.merchantId())).isEqualTo(1); |
| | | // 已经纳管过的商户号在核验里只说明会复用原记录,不能报成「门店已有进件」这种硬拦截。 |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId); |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId, APPLY_NO); |
| | | assertThat(preview).containsEntry("alreadyManaged", true); |
| | | assertThat((List<?>) preview.get("blockers")).isEmpty(); |
| | | } |
| | |
| | | |
| | | service.adopt(fixture.merchantId(), firstHuifuId, APPLY_NO, true); |
| | | |
| | | assertThat(service.preview(fixture.merchantId(), secondHuifuId).get("blockers")) |
| | | assertThat(service.preview(fixture.merchantId(), secondHuifuId, APPLY_NO).get("blockers")) |
| | | .asInstanceOf(org.assertj.core.api.InstanceOfAssertFactories.list(String.class)) |
| | | .anySatisfy(blocker -> assertThat(blocker).contains("同一门店出现两个收款主体")); |
| | | assertThatThrownBy(() -> service.adopt(fixture.merchantId(), secondHuifuId, APPLY_NO, true)) |
| | |
| | | jdbc.update("update merchant set can_login_merchant_app = 0 where id = ?", fixture.merchantId()); |
| | | stubConvergedChannel(huifuId, "622200001234", "external-card-token"); |
| | | |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId); |
| | | Map<String, Object> preview = service.preview(fixture.merchantId(), huifuId, APPLY_NO); |
| | | |
| | | assertThat(String.valueOf(preview.get("loginNotice"))).contains("未开启商户端登录"); |
| | | // 提示不阻挡纳管:纳管只管收款绑定,账号由「商家查询」负责。 |
| | |
| | | """, fixture.merchantId(), "t01ok" + Math.abs(System.nanoTime())); |
| | | stubConvergedChannel(huifuId, "622200001234", "external-card-token"); |
| | | |
| | | assertThat(service.preview(fixture.merchantId(), huifuId).get("loginNotice")).isEqualTo(""); |
| | | assertThat(service.preview(fixture.merchantId(), huifuId, APPLY_NO).get("loginNotice")).isEqualTo(""); |
| | | } |
| | | |
| | | /** |
| | |
| | | Map<String, Object> detail = channelDetail(huifuId, "622200001234", "token", "Y", true); |
| | | detail.put("qry_cash_card_info_list", List.of(Map.of("card_no", "6222****1234", "token_no", "masked-token"))); |
| | | when(gateway.queryCapabilities(huifuId)).thenReturn(detail); |
| | | // 申请单号这一关先放行,本用例只盯"没有可用结算卡":否则先撞上的是配对校验。 |
| | | when(gateway.queryApplication(anyString(), anyString())).thenReturn(Map.of("resp_code", "00000000")); |
| | | |
| | | assertThat(service.preview(fixture.merchantId(), huifuId).get("blockers")) |
| | | assertThat(service.preview(fixture.merchantId(), huifuId, APPLY_NO).get("blockers")) |
| | | .asInstanceOf(org.assertj.core.api.InstanceOfAssertFactories.list(String.class)) |
| | | .anySatisfy(blocker -> assertThat(blocker).contains("结算银行卡")); |
| | | assertThatThrownBy(() -> service.adopt(fixture.merchantId(), huifuId, APPLY_NO, true)) |
| | |
| | | .hasMessageContaining("结算银行卡"); |
| | | } |
| | | |
| | | /** |
| | | * 申请单号填错时必须在**建记录之前**被拦下,而且要说清是哪一栏错了。 |
| | | * |
| | | * <p>错号不会误放(基础审核确认不了、收不了款),真正的问题是它留下一具尸体:记录建出来了、 |
| | | * 刷新报的却是「汇付查询未成功,请稍后刷新」——看起来像通道抖动;而重复纳管是幂等的、不会用 |
| | | * 新号覆盖旧号,运营只能解绑重来。通道对这两个字段是**一起**校验的(填错的号,包括"真实存在但 |
| | | * 属于别的商户号"的号,都回 `00000001 申请单不存在`),所以这里配一次对就能拦住。 |
| | | */ |
| | | @Test |
| | | void adoptingWithAnApplyNumberThatDoesNotBelongToTheMerchantIsRejected() { |
| | | String huifuId = uniqueHuifuId(); |
| | | Fixture fixture = merchantFixture("号不匹配"); |
| | | when(gateway.queryCapabilities(huifuId)).thenReturn(channelDetail(huifuId, "622200001234", "card-token", "Y", true)); |
| | | when(gateway.queryApplication(anyString(), anyString())).thenReturn(Map.of("resp_code", "00000001", "resp_desc", "申请单不存在")); |
| | | |
| | | assertThatThrownBy(() -> service.adopt(fixture.merchantId(), huifuId, "999999999999999999", true)) |
| | | .isInstanceOf(BusinessException.class) |
| | | .hasMessageContaining("申请单号与该商户号不匹配") |
| | | .hasMessageContaining("申请单不存在"); |
| | | // 一具尸体都不该留下:进件记录与结算卡都不建。 |
| | | assertThat(jdbc.queryForObject("select count(*) from merchant_onboarding_application where merchant_id = ?", |
| | | Integer.class, fixture.merchantId())).isZero(); |
| | | assertThat(jdbc.queryForObject("select count(*) from merchant_bank_card where merchant_id = ?", |
| | | Integer.class, fixture.merchantId())).isZero(); |
| | | // 核验那一步也要提前把这条说出来,运营不用等提交。 |
| | | assertThat(service.preview(fixture.merchantId(), huifuId, "999999999999999999").get("blockers")) |
| | | .asInstanceOf(org.assertj.core.api.InstanceOfAssertFactories.list(String.class)) |
| | | .anySatisfy(blocker -> assertThat(blocker).contains("申请单不存在")); |
| | | } |
| | | |
| | | private Long adoptedApplicationId(Long merchantId, String huifuId) { |
| | | return jdbc.queryForObject("select id from merchant_onboarding_application where merchant_id = ? and provider_huifu_id = ?", |
| | | Long.class, merchantId, huifuId); |