Bläddra i källkod

feat: AlipayClientFactory 新增 getClientByProvider(providerId, bizType) - 账号级无企业中间层直取业务凭证

alphaH 1 vecka sedan
förälder
incheckning
1fcc3e924d

+ 19 - 0
java/src/main/java/com/payment/platform/core/alipay/AlipayClientFactory.java

@@ -105,6 +105,25 @@ public class AlipayClientFactory {
         return providerClients.computeIfAbsent(providerId, this::createClientForProvider);
     }
 
+    /**
+     * 按服务商 + 业务类型获取客户端(账号级场景,无企业中间层)
+     * <p>
+     * 解析优先级(与 {@link #getClient(String, String)} 企业链路同构,仅少企业中间层):
+     *   providerId + bizType → pay_service_provider_profile(业务专属凭证)
+     *   providerId → pay_service_provider(默认凭证,不存在/停用时内部回退默认客户端)
+     *   providerId 为 null → 默认客户端
+     */
+    public AlipayClient getClientByProvider(Long providerId, String bizType) {
+        if (providerId == null) return getClient();
+        if (bizType != null) {
+            // 1. 尝试业务专属凭证
+            AlipayClient profileClient = getClientByProfile(providerId, bizType);
+            if (profileClient != null) return profileClient;
+        }
+        // 2. 回退到服务商默认凭证
+        return getClientByProvider(providerId);
+    }
+
     /**
      * 强制刷新指定服务商客户端(配置修改后调用)
      */

+ 44 - 0
java/src/test/java/com/payment/platform/core/alipay/AlipayClientFactoryProfileTest.java

@@ -4,6 +4,7 @@ import com.alipay.api.AlipayClient;
 import com.payment.platform.module.payment.enterprise.entity.EnterpriseEntity;
 import com.payment.platform.module.payment.enterprise.mapper.EnterpriseMapper;
 import com.payment.platform.module.payment.openapi.mapper.OpenConfMapper;
+import com.payment.platform.module.payment.serviceprovider.entity.ServiceProviderEntity;
 import com.payment.platform.module.payment.serviceprovider.entity.ServiceProviderProfileEntity;
 import com.payment.platform.module.payment.serviceprovider.mapper.ServiceProviderMapper;
 import com.payment.platform.module.payment.serviceprovider.mapper.ServiceProviderProfileMapper;
@@ -17,7 +18,10 @@ import java.lang.reflect.Field;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 /**
@@ -141,4 +145,44 @@ class AlipayClientFactoryProfileTest {
         assertNotNull(client);
         assertNull(readCertField(client));
     }
+
+    // ==================== getClientByProvider(providerId, bizType) — 账号级直取 ====================
+
+    @Test
+    void getClientByProvider_bizType_profileFirst() throws Exception {
+        // 账号级: providerId + bizType 命中 profile → 业务专属客户端(不再落到服务商默认)
+        when(profileMapper.selectOne(any())).thenReturn(profile(true, false));
+
+        AlipayClient client = factory.getClientByProvider(1L, "BATCH_PAY");
+
+        assertNotNull(client, "profile 命中时应创建业务专属客户端");
+        verify(serviceProviderMapper, never()).selectById(any());
+    }
+
+    @Test
+    void getClientByProvider_bizType_noProfile_fallsBackToProvider() throws Exception {
+        // 无 profile → 回退服务商默认凭证(cert 模式)
+        when(profileMapper.selectOne(any())).thenReturn(null);
+        ServiceProviderEntity sp = new ServiceProviderEntity();
+        sp.setId(1L);
+        sp.setProviderStatus("ACTIVE");
+        sp.setAppId("app-provider");
+        sp.setAppPrivateKey("PRIVATE_KEY");
+        sp.setAlipayPublicKey("PUBLIC_KEY");
+        sp.setAppCertContent(TEST_CERT_PEM);
+        sp.setAlipayPublicCertContent(TEST_CERT_PEM);
+        sp.setRootCertContent(TEST_CERT_PEM);
+        when(serviceProviderMapper.selectById(1L)).thenReturn(sp);
+
+        AlipayClient client = factory.getClientByProvider(1L, "BATCH_PAY");
+
+        assertNotNull(client, "无 profile 时应回退服务商默认凭证客户端");
+        verify(serviceProviderMapper).selectById(1L);
+    }
+
+    @Test
+    void getClientByProvider_nullProvider_throwsWithoutFallback() {
+        // providerId 为 null → getClient(): 无 yml 默认配置且无 ACTIVE 服务商 → 明确抛异常(不静默)
+        assertThrows(IllegalStateException.class, () -> factory.getClientByProvider(null, "BATCH_PAY"));
+    }
 }