- Go 服务端:唯一金额/备注码/回填订单编号三路匹配、托管收银页、HMAC 回调七级重试、SQLite 单二进制 - SDK:Go / Java / PHP / Python,共享签名测试向量(docs/test_vectors.json) - 跨语言 e2e(真实二进制 × Python SDK × mock 币安)、GitHub Actions CI、Dockerfile - 协议文档 docs/protocol.md、调研与实测结论 docs/research.md Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
55 lines
2.6 KiB
Java
55 lines
2.6 KiB
Java
import com.bpaygate.sdk.BPayGateClient;
|
|
import com.google.gson.Gson;
|
|
import com.google.gson.JsonArray;
|
|
import com.google.gson.JsonObject;
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Paths;
|
|
|
|
/** 签名向量测试(无 JUnit 依赖,CI 中直接 java 运行;非零退出即失败)。 */
|
|
public class VectorTest {
|
|
public static void main(String[] args) throws Exception {
|
|
String path = args.length > 0 ? args[0] : "../../docs/test_vectors.json";
|
|
String raw = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
|
|
JsonObject vf = new Gson().fromJson(raw, JsonObject.class);
|
|
String secret = vf.get("secret").getAsString();
|
|
JsonArray cases = vf.getAsJsonArray("cases");
|
|
int fails = 0;
|
|
for (int i = 0; i < cases.size(); i++) {
|
|
JsonObject c = cases.get(i).getAsJsonObject();
|
|
String got;
|
|
if ("request".equals(c.get("type").getAsString())) {
|
|
got = BPayGateClient.signRequest(secret, c.get("timestamp").getAsString(),
|
|
c.get("nonce").getAsString(), c.get("method").getAsString(),
|
|
c.get("path").getAsString(), c.get("body").getAsString());
|
|
} else {
|
|
got = BPayGateClient.signCallback(secret, c.get("timestamp").getAsString(),
|
|
c.get("nonce").getAsString(), c.get("body").getAsString());
|
|
}
|
|
if (!got.equals(c.get("signature").getAsString())) {
|
|
System.err.println("case " + i + ": got " + got + " want " + c.get("signature").getAsString());
|
|
fails++;
|
|
}
|
|
}
|
|
// verifyCallback 正反例
|
|
String body = "{\"event\":\"paid\",\"merchant_order_id\":\"M1\"}";
|
|
String ts = String.valueOf(System.currentTimeMillis());
|
|
String sig = BPayGateClient.signCallback(secret, ts, "nnnnnnnnnnnnnnnnnnnn", body);
|
|
JsonObject payload = BPayGateClient.verifyCallback(ts, "nnnnnnnnnnnnnnnnnnnn", sig, body, secret, 300000);
|
|
if (!"paid".equals(payload.get("event").getAsString())) {
|
|
System.err.println("verifyCallback 解析失败");
|
|
fails++;
|
|
}
|
|
try {
|
|
BPayGateClient.verifyCallback(ts, "nnnnnnnnnnnnnnnnnnnn", "bad", body, secret, 300000);
|
|
System.err.println("坏签名未被拒绝");
|
|
fails++;
|
|
} catch (BPayGateClient.BPayGateException e) {
|
|
// 预期
|
|
}
|
|
if (fails > 0) System.exit(1);
|
|
System.out.println("Java SDK vectors: ALL PASS");
|
|
}
|
|
}
|