源:https://blog.ximinghui.org/db407a4b/index.html
〇. 注册VISA开发者中心账号
如果已注册过,请跳过该步,否则参考 VISA信用卡的SDK示范(Hello World) 进行注册。
一. 创建一个项目
如果已创建过,请跳过该步,否则参考 VISA信用卡的SDK示范(Hello World) 进行创建。
二、准备jks文件
如果已经有了jks文件,请跳过该步,否则参考VISA信用卡的SDK示范(Hello World)文章中的 三、Two-Way/Mutual SSL认证方式 部分生成jks文件。
三、创建VISA证书信任库(Trust Store)
1. 从VISA开发者中心下载证书
进入VISA开发者中心页面左侧的“Credentials”界面,根据下面说明或点击 这里 参考图片中标出来的红、绿、蓝框。
点击 "Sandbox Root CA" 链接下载 根证书(Root Certificate)
,将会下载一个 SBX-2024-Prod-Root.pem
这样的文件;
点击 "Sandbox Issuing CA" 链接下载 中间证书(Intermediate Certificate)
,将会下载一个 SBX-2024-Prod-Inter.pem
这样的文件;
点击 "DigiCert Global Root CA certificate" 链接下载 DigiCert根证书
,将会下载一个 DigiCertGlobalRootCA.crt
这样的文件。
2. 创建信任库
接下来使用上面下载的3个证书创建信任库。
说明:下面命令将信任库创建在 C:\Users\ximinghui\Downloads\
目录,且3个证书都也都位于该目录,示例密码密码为 123456
, 请根据实际情况调整路径和密码。
# 创建信任库
keytool -genkey -alias dummy -keyalg RSA -keystore "C:\Users\ximinghui\Downloads\visa_truststore.jks" -storepass 123456 -keypass 123456 -dname "CN=dummy"
# 删除临时条目
keytool -delete -alias dummy -keystore "C:\Users\ximinghui\Downloads\visa_truststore.jks" -storepass 123456
# 导入3个证书(DigiCert Root CA、Visa Root Certificate、Visa Intermediate Certificate)
keytool -import -trustcacerts -alias digicert-root -file "C:\Users\ximinghui\Downloads\DigiCertGlobalRootCA.crt" -keystore "C:\Users\ximinghui\Downloads\visa_truststore.jks" -storepass 123456
keytool -import -trustcacerts -alias visa-root -file "C:\Users\ximinghui\Downloads\SBX-2024-Prod-Root.pem" -keystore "C:\Users\ximinghui\Downloads\visa_truststore.jks" -storepass 123456
keytool -import -trustcacerts -alias visa-intermediate -file "C:\Users\ximinghui\Downloads\SBX-2024-Prod-Inter.pem" -keystore "C:\Users\ximinghui\Downloads\visa_truststore.jks" -storepass 123456
四、测试VISA的PullFunds API
VISA开发者中心项目详情页侧边栏进入Assert页面,可以找到一些示范代码(GitHub仓库中的代码位置为https://github.com/vandofb/visa-java-sample-code/tree/master/vdp-sample-java-funds-transfer)。以下贴出的是我参考vdp-sample-java-funds-transfer写的Demo。
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.security.KeyStore;
import java.util.Base64;
import java.util.UUID;
public class Test {
public static void main(String[] args) throws Exception {
String username = "替换成你的username";
String password = "替换成你的password";
// 更新localTransactionDateTime时间为调用时的时间(注意时区)
String requestBody = """
{
"systemsTraceAuditNumber": "451001",
"surcharge": "11.99",
"senderPrimaryAccountNumber": "4895142232120006",
"senderCurrencyCode": "USD",
"senderCardExpiryDate": "2015-10",
"retrievalReferenceNumber": "330000550000",
"localTransactionDateTime": "2024-12-27T07:15:50",
"foreignExchangeFeeTransaction": "11.99",
"cavv": "0700100038238906000013405823891061668252",
"cardAcceptor": {
"terminalId": "ABCD1234",
"name": "Visa Inc. USA-Foster City",
"idCode": "ABCD1234ABCD123",
"address": {
"zipCode": "94404",
"state": "CA",
"county": "San Mateo",
"country": "USA"
}
},
"businessApplicationId": "AA",
"amount": "124.02",
"acquiringBin": "408999",
"acquirerCountryCode": "840"
}
""";
// 构建 HttpClient
HttpClient httpClient = HttpClient.newBuilder()
.sslContext(createSSLContext())
.version(HttpClient.Version.HTTP_2)
.build();
// 构建 HttpRequest
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://sandbox.api.visa.com/visadirect/fundstransfer/v1/pullfundstransactions"))
.header("Authorization", "Basic " + Base64.getEncoder().encodeToString((username + ":" + password).getBytes()))
.header("ex-correlation-id", UUID.randomUUID().toString().replace("-", "").substring(0, 10) + "_SC")
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(requestBody))
.build();
// 发送请求并接收响应
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
// 输出响应信息
System.out.println("Response Code: " + response.statusCode());
System.out.println("Response Body: " + response.body());
}
private static SSLContext createSSLContext() throws Exception {
String keystorePath = "替换成你的路径,我的是C:/Users/ximinghui/Downloads/key.jks";
String trustStorePath = "替换成你的路径,我的是C:/Users/ximinghui/Downloads/visa_truststore.jks";
String keystorePassword = "替换成你的keystorePassword,我的是C000000";
String trustStorePassword = "替换成你的trustStorePassword,我的是123456";
// 加载密钥库(客户端证书)
KeyStore keyStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(keystorePath)) {
keyStore.load(fis, keystorePassword.toCharArray());
}
// 加载信任库(Visa的证书)
KeyStore trustStore = KeyStore.getInstance("JKS");
try (FileInputStream fis = new FileInputStream(trustStorePath)) {
trustStore.load(fis, trustStorePassword.toCharArray());
}
// 初始化 KeyManagerFactory
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keystorePassword.toCharArray());
// 初始化 TrustManagerFactory
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
// 配置 SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);
return sslContext;
}
}
运行代码,调用API成功响应的状态码是2xx,响应体如下:
{
"transactionIdentifier": 429311337027961,
"actionCode": "00",
"approvalCode": "98765X",
"responseCode": "5",
"transmissionDateTime": "2024-12-27T09:39:48.000Z",
"cavvResultCode": "8",
"cpsAuthorizationCharacteristicsIndicator": "3333"
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。