Files
pangolin/server/internal/pay/catalog.go
T
wangjia 7ac9fa40f0 feat(server/pay): catalog 加全员优惠月付 pro_month_promo(¥6/$1)+ Promo 标记
优惠档全员可见,客户端用特殊卡片展示;pay 侧需种同 biz_code 商品后方可真下单
(未种前 product_not_found→404,UI 先就绪)。catalog 测试更新为 4 档 + promo 断言。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
2026-07-12 19:27:34 +08:00

57 lines
2.5 KiB
Go

package pay
import "github.com/wangjia/pangolin/server/internal/codes"
// CatalogItem 是可购档位。SKU 与 pay 侧 products.biz_code 一一对应
// (webhook product_biz_code 原样回带);价格字段**仅展示**(实际扣款以 pay 侧
// per-currency ProductPrice 为准——一致性列入联调 checklist):
// - PriceMinor:CNY 分(支付宝/哪吒等法币渠道)
// - PriceUsdtMicro:USDT 微元(6 位精度,加密货币渠道)
type CatalogItem struct {
SKU string `json:"sku"`
Plan string `json:"plan"`
Days int `json:"days"`
PriceMinor int64 `json:"price_minor"` // CNY 分(展示)
Currency string `json:"currency"` // CNY
PriceUsdtMicro int64 `json:"price_usdt_micro"` // USDT 微元(展示;各币种一口价、非汇率换算)
Promo bool `json:"promo,omitempty"` // true=优惠档,客户端用特殊卡片展示(全员可见)
}
// Catalog 单源。时长取宽松口径(31/92/366 覆盖大月与最长季)。
// USDT 展示价与 pay 侧 products 一口价对齐,不做实时汇率换算。
// pro_month_promo 是全员优惠月付(¥6/$1);**pay 侧需种同 biz_code 商品后方可真下单**,
// 未种前下单 pay 回 product_not_found → 404(UI 先就绪)。
var Catalog = []CatalogItem{
{SKU: "pro_month_promo", Plan: string(codes.PlanPro), Days: 31, PriceMinor: 600, Currency: "CNY", PriceUsdtMicro: 1000000, Promo: true},
{SKU: "pro_month", Plan: string(codes.PlanPro), Days: 31, PriceMinor: 2999, Currency: "CNY", PriceUsdtMicro: 4990000},
{SKU: "pro_quarter", Plan: string(codes.PlanPro), Days: 92, PriceMinor: 6888, Currency: "CNY", PriceUsdtMicro: 12990000},
{SKU: "pro_year", Plan: string(codes.PlanPro), Days: 366, PriceMinor: 19999, Currency: "CNY", PriceUsdtMicro: 34990000},
}
func CatalogBySKU(sku string) (CatalogItem, bool) {
for _, it := range Catalog {
if it.SKU == sku {
return it, true
}
}
return CatalogItem{}, false
}
// SettlementCurrency 按支付方式给出结算币种(展示/落台账用;实际以 pay 侧为准)。
// crypto→USDT;其余法币渠道(alipay/nezha/…)→CNY。
func SettlementCurrency(method string) string {
if method == "crypto" {
return "USDT"
}
return "CNY"
}
// DisplayAmountMinor 按支付方式给出该档「展示金额」(下单时预估、落台账,
// webhook 到账后由实际结算金额覆盖)。crypto→USDT 微元;法币→CNY 分。
func DisplayAmountMinor(it CatalogItem, method string) int64 {
if method == "crypto" {
return it.PriceUsdtMicro
}
return it.PriceMinor
}