52 lines
1.3 KiB
Go
52 lines
1.3 KiB
Go
|
package payment
|
|||
|
|
|||
|
import (
|
|||
|
"crypto/rand"
|
|||
|
"encoding/hex"
|
|||
|
"fmt"
|
|||
|
"strconv"
|
|||
|
"sync/atomic"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
const (
|
|||
|
// 订单号前缀
|
|||
|
AlipayPrefix = "ALI" // 支付宝订单前缀
|
|||
|
WechatPrefix = "WX" // 微信支付订单前缀
|
|||
|
ApplePrefix = "APP" // 苹果支付订单前缀
|
|||
|
)
|
|||
|
|
|||
|
const (
|
|||
|
RefundPrefix = "REF" // 退款订单前缀
|
|||
|
)
|
|||
|
|
|||
|
// 全局原子计数器
|
|||
|
var orderCounter uint32 = 0
|
|||
|
|
|||
|
// GenerateOrderNo 生成统一格式的订单号
|
|||
|
// prefix: 订单前缀(ALI/WX/APP)
|
|||
|
// 返回格式:前缀 + 时间戳(10位) + 计数器(6位) + 随机数(6位)
|
|||
|
// 例如:ALI202403151234567890123456
|
|||
|
func GenerateOrderNo(prefix string) string {
|
|||
|
// 获取当前时间戳(秒级)
|
|||
|
timestamp := time.Now().Unix()
|
|||
|
timeStr := strconv.FormatInt(timestamp, 10)
|
|||
|
|
|||
|
// 原子递增计数器
|
|||
|
counter := atomic.AddUint32(&orderCounter, 1)
|
|||
|
|
|||
|
// 生成4字节真随机数
|
|||
|
randomBytes := make([]byte, 4)
|
|||
|
_, err := rand.Read(randomBytes)
|
|||
|
if err != nil {
|
|||
|
// 如果随机数生成失败,回退到使用时间纳秒数据
|
|||
|
randomBytes = []byte(strconv.FormatInt(time.Now().UnixNano()%1000000, 16))
|
|||
|
}
|
|||
|
randomHex := hex.EncodeToString(randomBytes)
|
|||
|
|
|||
|
// 组合所有部分: 前缀 + 时间戳 + 计数器 + 随机数
|
|||
|
orderNo := fmt.Sprintf("%s_%s%06x%s", prefix, timeStr, counter%0xFFFFFF, randomHex[:6])
|
|||
|
|
|||
|
return orderNo
|
|||
|
}
|