// Package alipay 支付宝支付能力封装 // 提供 client 构建、金额转换、WAP 支付链接生成、回调验签等辅助函数 package alipay import ( "fmt" "strings" ) // FenToYuan 将分(整数)转换为元字符串,精确到小数点后两位。 // 例如:123 -> "1.23",100 -> "1.00",1 -> "0.01" func FenToYuan(amountFen int64) string { // 整除得元,取余得分 yuan := amountFen / 100 fen := amountFen % 100 if fen < 0 { fen = -fen } return fmt.Sprintf("%d.%02d", yuan, fen) } // YuanToFen 将元字符串转换为分(整数)。 // 只接受合法金额格式:最多两位小数,纯数字加可选小数点,拒绝科学计数法和负数。 // 例如:"1.23" -> 123,"1.00" -> 100,"1" -> 100 func YuanToFen(value string) (int64, error) { value = strings.TrimSpace(value) if value == "" { return 0, fmt.Errorf("金额字符串不能为空") } // 禁止负数 if strings.HasPrefix(value, "-") { return 0, fmt.Errorf("金额不能为负数: %s", value) } // 禁止科学计数法 if strings.ContainsAny(value, "eE") { return 0, fmt.Errorf("金额格式非法,禁止科学计数法: %s", value) } parts := strings.Split(value, ".") if len(parts) > 2 { return 0, fmt.Errorf("金额格式非法: %s", value) } // 校验整数部分 yuanStr := parts[0] if !isDigits(yuanStr) { return 0, fmt.Errorf("金额格式非法: %s", value) } // 解析整数部分 var yuan int64 for _, c := range yuanStr { yuan = yuan*10 + int64(c-'0') } var fen int64 if len(parts) == 2 { fenStr := parts[1] if len(fenStr) == 0 || len(fenStr) > 2 { return 0, fmt.Errorf("金额小数位数非法(最多两位): %s", value) } if !isDigits(fenStr) { return 0, fmt.Errorf("金额格式非法: %s", value) } // 补齐到两位 if len(fenStr) == 1 { fenStr += "0" } for _, c := range fenStr { fen = fen*10 + int64(c-'0') } } return yuan*100 + fen, nil } // isDigits 判断字符串是否全为数字字符 func isDigits(s string) bool { if s == "" { return false } for _, c := range s { if c < '0' || c > '9' { return false } } return true }