支持拉卡拉多渠道支付和测试充值

This commit is contained in:
yml
2026-06-06 21:46:41 +08:00
parent 4d40883da6
commit ba4c56c0cc
16 changed files with 1917 additions and 157 deletions
@@ -0,0 +1,90 @@
package lakala
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"strings"
"testing"
)
func TestVerifyNotifyDetail(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("generate key: %v", err)
}
privatePEM, certPEM := testKeyPairPEM(t, key)
client := NewClient(Config{
GatewayURL: "https://example.com",
AppID: "app-1",
SerialNo: "serial-1",
MerchantID: "merchant-1",
PrivateKey: privatePEM,
NotifyCert: certPEM,
})
body := `{"req_data":{"out_order_no":"NO1","total_amount":100,"trade_state":"SUCCESS"}}`
message := "1710000000\nabc123\n" + body + "\n"
signature, err := signRSA(key, []byte(message))
if err != nil {
t.Fatalf("signRSA: %v", err)
}
authorization := `LKLAPI-SHA256withRSA timestamp="1710000000",nonce_str="abc123",signature="` + signature + `"`
result := client.VerifyNotifyDetail(body, authorization)
if !result.OK {
t.Fatalf("VerifyNotifyDetail().OK = false, got=%s expected=%v base=%v", result.Got, result.Expected, result.BaseString)
}
tampered := client.VerifyNotifyDetail(strings.Replace(body, "100", "101", 1), authorization)
if tampered.OK {
t.Fatal("VerifyNotifyDetail() = true after body changed, want false")
}
}
func TestParsePayloadNormalizesAliases(t *testing.T) {
params, err := ParsePayload([]byte(`{
"req_data": {
"out_order_no": "ORDER1",
"pay_order_no": "PAY1",
"total_amount": 88,
"trade_state": "SUCCESS",
"trade_time": "20240521101010"
}
}`))
if err != nil {
t.Fatalf("ParsePayload error = %v", err)
}
if params["third_order_id"] != "ORDER1" {
t.Fatalf("third_order_id = %q, want ORDER1", params["third_order_id"])
}
if params["provider_order_id"] != "PAY1" {
t.Fatalf("provider_order_id = %q, want PAY1", params["provider_order_id"])
}
if params["amount"] != "88" {
t.Fatalf("amount = %q, want 88", params["amount"])
}
if params["status"] != "paid" {
t.Fatalf("status = %q, want paid", params["status"])
}
}
func testKeyPairPEM(t *testing.T, key *rsa.PrivateKey) (string, string) {
t.Helper()
privateDER := x509.MarshalPKCS1PrivateKey(key)
privatePEM := string(pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privateDER,
}))
template := &x509.Certificate{}
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
if err != nil {
t.Fatalf("create certificate: %v", err)
}
certPEM := string(pem.EncodeToMemory(&pem.Block{
Type: "CERTIFICATE",
Bytes: certDER,
}))
return privatePEM, certPEM
}