Browse Source

10月27日银行接口demo

huangqizheng/feature-20251104113536-现金管理二期退款修改
sunjiabei 1 month ago
parent
commit
b671f447f4
  1. 15
      pom.xml
  2. 28
      src/main/java/com/example/demo/DemoApplicationBank.java
  3. 23
      src/main/java/com/example/demo/bank/Server.java
  4. 46
      src/main/java/com/example/demo/config/AppConfig.java
  5. 44
      src/main/java/com/example/demo/controller/cash/BankController.java
  6. 21
      src/main/java/com/example/demo/domain/DTO/BankDTO.java
  7. 30
      src/main/java/com/example/demo/domain/DTO/PaymentDTO.java
  8. 19
      src/main/java/com/example/demo/domain/vo/cash/Bank.java
  9. 18
      src/main/java/com/example/demo/service/cash/BankService.java
  10. 137
      src/main/java/com/example/demo/serviceImpl/cash/BankServiceImpl.java

15
pom.xml

@ -166,6 +166,21 @@
<artifactId>jaxb-api</artifactId> <artifactId>jaxb-api</artifactId>
<version>2.3.1</version> <version>2.3.1</version>
</dependency> </dependency>
<dependency>
<groupId>com.stripe</groupId>
<artifactId>stripe-java</artifactId>
<version>30.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
</dependencies> </dependencies>
<!--配置多环境打包--> <!--配置多环境打包-->

28
src/main/java/com/example/demo/DemoApplicationBank.java

@ -0,0 +1,28 @@
package com.example.demo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling // 启用调度功能
@SpringBootApplication
@MapperScan(basePackages = "com.example.demo.mapper.coin", sqlSessionTemplateRef = "mysql1SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.bean", sqlSessionTemplateRef = "mysql2SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.pay", sqlSessionTemplateRef = "mysql3SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.cms", sqlSessionTemplateRef = "mysql4SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.live", sqlSessionTemplateRef = "mysql5SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.sqlserver", sqlSessionTemplateRef = "sqlserver1SqlSessionTemplate")
@MapperScan(basePackages = "com.example.demo.mapper.cash", sqlSessionTemplateRef = "mysql1SqlSessionTemplate")
public class DemoApplicationBank {
public static void main(String[] args) {
System.setProperty("https.protocols", "TLSv1,TLSv1.2,TLSv1.3");
// 设置客户端协议版本
System.setProperty("jdk.tls.client.protocols", "TLSv1,TLSv1.2,TLSv1.3");
SpringApplication.run(DemoApplication.class, args);
}
}

23
src/main/java/com/example/demo/bank/Server.java

@ -0,0 +1,23 @@
package com.example.demo.bank;
import com.stripe.Stripe;
import com.stripe.exception.StripeException;
import com.stripe.model.*;
import com.stripe.param.BalanceTransactionListParams;
import com.stripe.param.PaymentIntentSearchParams;
import com.stripe.param.ProductCreateParams;
import com.stripe.param.PriceCreateParams;
public class Server {
public static void main(String[] args) throws StripeException {
Stripe.apiKey = "sk_test_51SKwgEQqF1eV5j2cyHz7uZ28OsPHzt9nXv1DCOmr4buFHpGhhgmskCz2XOxtCbbQMZIEkELTWIlMgZWcK6PeflZj00nRijQkLx";
BalanceTransactionListParams params =
BalanceTransactionListParams.builder().setLimit(3L).build();
BalanceTransactionCollection balanceTransactions = BalanceTransaction.list(params);
System.out.println(balanceTransactions);
BalanceTransaction balanceTransaction =
BalanceTransaction.retrieve("txn_3SKxVWQqF1eV5j2c07IJegQv");
System.out.println(balanceTransaction);
}
}

46
src/main/java/com/example/demo/config/AppConfig.java

@ -2,16 +2,60 @@ package com.example.demo.config;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
@Configuration @Configuration
public class AppConfig { public class AppConfig {
@Bean @Bean
public RestTemplate restTemplate() {
public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException {
RestTemplate restTemplate = new RestTemplate(); RestTemplate restTemplate = new RestTemplate();
// 配置SSL支持
restTemplate.setRequestFactory(createSSLRequestFactory());
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter()); restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
return restTemplate; return restTemplate;
} }
/**
* 创建支持SSL的HTTP请求工厂
*/
private ClientHttpRequestFactory createSSLRequestFactory() throws NoSuchAlgorithmException, KeyManagementException {
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
} }
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
// 创建主机名验证器信任所有主机
HostnameVerifier allHostsValid = (hostname, session) -> true;
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(30000); // 30秒连接超时
factory.setReadTimeout(60000); // 60秒读取超时
return factory;
}
}

44
src/main/java/com/example/demo/controller/cash/BankController.java

@ -0,0 +1,44 @@
package com.example.demo.controller.cash;
import com.example.demo.config.interfac.Log;
import com.example.demo.domain.DTO.BankDTO;
import com.example.demo.domain.vo.cash.Bank;
import com.example.demo.domain.vo.coin.AuditRequest;
import com.example.demo.domain.vo.coin.Result;
import com.example.demo.service.cash.BankService;
import com.example.demo.service.cash.CashAuditService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* @program: gold-java
* @ClassName BankController
* @description:
* @author: Double
* @create: 202510-27 10:50
* @Version 1.0
**/
@RestController
@RequestMapping("/admin/bank")
@RequiredArgsConstructor
@Slf4j
@CrossOrigin
public class BankController {
@Autowired
private BankService bankService;
//payment银行接口
@Log("payment银行接口")
@PostMapping("/payment")
public Result payment(@RequestBody Bank bank){
try {
BankDTO bankDTO = bankService.payment(bank);
return Result.success(bankDTO);
}catch (Exception e){
return Result.error(e.getMessage());
}}
}

21
src/main/java/com/example/demo/domain/DTO/BankDTO.java

@ -0,0 +1,21 @@
package com.example.demo.domain.DTO;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @program: gold-java
* @ClassName BankDTO
* @description:
* @author: Double
* @create: 202510-27 11:16
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class BankDTO {
private List<PaymentDTO> paymentDTOList;
}

30
src/main/java/com/example/demo/domain/DTO/PaymentDTO.java

@ -0,0 +1,30 @@
package com.example.demo.domain.DTO;
/**
* @program: gold-java
* @ClassName PaymentDTO
* @description:
* @author: Double
* @create: 202510-27 13:35
* @Version 1.0
**/
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class PaymentDTO {
private String type;
private String provider;
private String request_reference;
private String merchant_reference;
private String provider_reference;
private String currency;
private String order_amount;
private String charge;
private String net_amount;
private String status;
private String created_time;
private String completed_time;
}

19
src/main/java/com/example/demo/domain/vo/cash/Bank.java

@ -0,0 +1,19 @@
package com.example.demo.domain.vo.cash;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @program: gold-java
* @ClassName BankDTO
* @description:
* @author: Double
* @create: 202510-27 11:11
* @Version 1.0
**/
@Data
@NoArgsConstructor
public class Bank {
private String time = "";
}

18
src/main/java/com/example/demo/service/cash/BankService.java

@ -0,0 +1,18 @@
package com.example.demo.service.cash;
import com.example.demo.domain.DTO.BankDTO;
import com.example.demo.domain.vo.cash.Bank;
/**
* @program: gold-java
* @ClassName BankService
* @description:
* @author: Double
* @create: 202510-27 11:17
* @Version 1.0
**/
public interface BankService {
BankDTO payment(Bank bank);
}

137
src/main/java/com/example/demo/serviceImpl/cash/BankServiceImpl.java

@ -0,0 +1,137 @@
package com.example.demo.serviceImpl.cash;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.domain.DTO.BankDTO;
import com.example.demo.domain.DTO.PaymentDTO;
import com.example.demo.domain.vo.cash.Bank;
import com.example.demo.service.cash.BankService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* @program: gold-java
* @ClassName BankServiceImpl
* @description:
* @author: Double
* @create: 202510-27 11:18
* @Version 1.0
**/
@Service
@Slf4j
public class BankServiceImpl implements BankService {
// 第三方API地址
private static final String API_URL = "https://gateway.pa-sys.com/v1.1/reconciliation/519e26b2-8145-418c-b3e7-c1e88e52b946/settlement";
// 签名密钥与PHP中的$secret一致
private static final String SECRET = "8987d1b8-1d82-4b15-af06-828d0b12076f";
// 注入RestTemplate用于HTTP请求需在Spring配置类中定义
private final RestTemplate restTemplate;
public BankServiceImpl(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
@Override
public BankDTO payment(Bank bank) {
try {
// 1. 准备参数
String settlementDate = bank.getTime(); // 从Bank对象获取time作为settlement_date
String network = "FPS"; // 固定值
// 2. 生成签名复刻PHP逻辑此处无需修改
Map<String, String> params = new TreeMap<>(); // 按key升序排序
params.put("settlement_date", settlementDate);
params.put("network", network);
String signSource = buildQueryString(params) + SECRET;
String sign = sha512(signSource);
// 3. 构建form-data请求参数
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("settlement_date", settlementDate);
formData.add("network", network);
formData.add("sign", sign);
// 4. 发送HTTP POST请求优化显式设置multipart/form-data的字符集
HttpHeaders headers = new HttpHeaders();
// 补充charset=UTF-8避免部分服务器对编码敏感
headers.setContentType(new MediaType("multipart", "form-data", StandardCharsets.UTF_8));
HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(formData, headers);
// 调用第三方API使用配置好SSL协议的RestTemplate
ResponseEntity<String> response = restTemplate.exchange(
API_URL,
HttpMethod.POST,
requestEntity,
String.class
);
if (response.getStatusCode().is2xxSuccessful()) {
String responseBody = response.getBody();
log.info("第三方API响应: {}", responseBody);
// 解析JSON获取payload.transactions数组
JSONObject jsonObject = JSON.parseObject(responseBody);
JSONArray transactions = jsonObject.getJSONObject("payload").getJSONArray("transactions");
// 创建BankDTO并设置paymentDTOList
BankDTO bankDTO = new BankDTO();
List<PaymentDTO> paymentDTOList = transactions.toJavaList(PaymentDTO.class);
bankDTO.setPaymentDTOList(paymentDTOList);
return bankDTO;
} else {
throw new RuntimeException("API请求失败,状态码: " + response.getStatusCodeValue());
}
} catch (Exception e) {
log.error("payment银行接口处理失败", e);
throw new RuntimeException("处理失败: " + e.getMessage());
}
}
/**
* http_build_query的查询字符串key=value&key=value
*/
private String buildQueryString(Map<String, String> params) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (sb.length() > 0) {
sb.append("&");
}
sb.append(entry.getKey()).append("=").append(entry.getValue());
}
return sb.toString();
}
/**
* SHA512加密
*/
private String sha512(String content) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] bytes = md.digest(content.getBytes(StandardCharsets.UTF_8));
// 转换为十六进制字符串
StringBuilder hexStr = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexStr.append('0');
}
hexStr.append(hex);
}
return hexStr.toString();
}
}
Loading…
Cancel
Save