更新易支付
This commit is contained in:
@@ -36,7 +36,7 @@ func seedDefaults(ctx context.Context, db *gorm.DB) error {
|
|||||||
{Key: "credits.invite_reward", Value: "3"},
|
{Key: "credits.invite_reward", Value: "3"},
|
||||||
{Key: "credits.cdk_redeem_enabled", Value: "true"},
|
{Key: "credits.cdk_redeem_enabled", Value: "true"},
|
||||||
{Key: "pay.enabled", Value: "false"},
|
{Key: "pay.enabled", Value: "false"},
|
||||||
{Key: "pay.api_base", Value: "https://pay.v8jisu.cn/api/pay"},
|
{Key: "pay.api_base", Value: "https://www.ezfpy.cn"},
|
||||||
{Key: "pay.methods", Value: "wxpay,alipay"},
|
{Key: "pay.methods", Value: "wxpay,alipay"},
|
||||||
{Key: "pay.min_amount", Value: "1"},
|
{Key: "pay.min_amount", Value: "1"},
|
||||||
{Key: "pay.points_ratio", Value: "100"},
|
{Key: "pay.points_ratio", Value: "100"},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// Package epay implements the 易支付 mapi (API 下单) interface with MD5 signing.
|
// Package epay implements the 易支付 mapi (API 下单) interface with MD5 signing.
|
||||||
// POST {api_base}/mapi → JSON {code, msg, trade_no, payurl, qrcode}.
|
// POST {api_base}/mapi.php → JSON {code, msg, trade_no, payurl, qrcode}.
|
||||||
// Docs: 请求字段 pid/type/out_trade_no/notify_url/name/money/sign/sign_type.
|
// Docs: 请求字段 pid/type/out_trade_no/notify_url/return_url/name/money/sign/sign_type.
|
||||||
package epay
|
package epay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
APIBase string // 易支付 API 根地址,如 https://pay.v8jisu.cn/api/pay(自动拼 /mapi)
|
APIBase string // 易支付站点根地址,如 https://www.ezfpy.cn(自动拼 /mapi.php)
|
||||||
PID string // 商户ID
|
PID string // 商户ID
|
||||||
Key string // 商户密钥
|
Key string // 商户密钥
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ type CreateRequest struct {
|
|||||||
Name string
|
Name string
|
||||||
Money string // "10.00"
|
Money string // "10.00"
|
||||||
NotifyURL string
|
NotifyURL string
|
||||||
ReturnURL string
|
ReturnURL string // 页面跳转通知地址(必填)
|
||||||
ClientIP string // unused by mapi; kept for caller convenience
|
ClientIP string // unused by mapi; kept for caller convenience
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ type CreateResult struct {
|
|||||||
PayInfo string // 二维码内容 或 跳转 url
|
PayInfo string // 二维码内容 或 跳转 url
|
||||||
}
|
}
|
||||||
|
|
||||||
// mapiResp is the raw mapi response. code: 1 成功, -1 失败.
|
// mapiResp is the raw mapi response. code: 1 或 200 为成功,其它为失败.
|
||||||
type mapiResp struct {
|
type mapiResp struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
@@ -85,18 +85,16 @@ func (c *Config) Create(ctx context.Context, req CreateRequest) (*CreateResult,
|
|||||||
"notify_url": req.NotifyURL,
|
"notify_url": req.NotifyURL,
|
||||||
"name": req.Name,
|
"name": req.Name,
|
||||||
"money": req.Money,
|
"money": req.Money,
|
||||||
|
"return_url": req.ReturnURL,
|
||||||
"sign_type": "MD5",
|
"sign_type": "MD5",
|
||||||
}
|
}
|
||||||
if req.ReturnURL != "" {
|
|
||||||
params["return_url"] = req.ReturnURL
|
|
||||||
}
|
|
||||||
params["sign"] = sign(params, c.Key)
|
params["sign"] = sign(params, c.Key)
|
||||||
|
|
||||||
form := url.Values{}
|
form := url.Values{}
|
||||||
for k, v := range params {
|
for k, v := range params {
|
||||||
form.Set(k, v)
|
form.Set(k, v)
|
||||||
}
|
}
|
||||||
endpoint := strings.TrimRight(c.APIBase, "/") + "/mapi"
|
endpoint := strings.TrimRight(c.APIBase, "/") + "/mapi.php"
|
||||||
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, strings.NewReader(form.Encode()))
|
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, strings.NewReader(form.Encode()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -112,7 +110,7 @@ func (c *Config) Create(ctx context.Context, req CreateRequest) (*CreateResult,
|
|||||||
if err := json.Unmarshal(body, &out); err != nil {
|
if err := json.Unmarshal(body, &out); err != nil {
|
||||||
return nil, fmt.Errorf("epay: bad response: %s", strings.TrimSpace(string(body)))
|
return nil, fmt.Errorf("epay: bad response: %s", strings.TrimSpace(string(body)))
|
||||||
}
|
}
|
||||||
if out.Code != 1 {
|
if out.Code != 1 && out.Code != 200 {
|
||||||
msg := out.Msg
|
msg := out.Msg
|
||||||
if msg == "" {
|
if msg == "" {
|
||||||
msg = "下单失败"
|
msg = "下单失败"
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type PaySettings struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
PID string `json:"pid"`
|
PID string `json:"pid"`
|
||||||
Key string `json:"key"`
|
Key string `json:"key"`
|
||||||
APIBase string `json:"api_base"` // 易支付站点根地址,代码自动拼 /api/pay/create
|
APIBase string `json:"api_base"` // 易支付站点根地址,代码自动拼 /mapi.php
|
||||||
Methods []string `json:"methods"` // wxpay, alipay
|
Methods []string `json:"methods"` // wxpay, alipay
|
||||||
MinAmount float64 `json:"min_amount"`
|
MinAmount float64 `json:"min_amount"`
|
||||||
PointsRatio int `json:"points_ratio"` // 积分 per 元
|
PointsRatio int `json:"points_ratio"` // 积分 per 元
|
||||||
@@ -56,7 +56,7 @@ func (s *PaymentService) get(ctx context.Context, key string) string {
|
|||||||
func (s *PaymentService) Settings(ctx context.Context) PaySettings {
|
func (s *PaymentService) Settings(ctx context.Context) PaySettings {
|
||||||
api := strings.TrimRight(strings.TrimSpace(s.get(ctx, "pay.api_base")), "/")
|
api := strings.TrimRight(strings.TrimSpace(s.get(ctx, "pay.api_base")), "/")
|
||||||
if api == "" {
|
if api == "" {
|
||||||
api = "https://pay.v8jisu.cn/api/pay"
|
api = "https://www.ezfpy.cn"
|
||||||
}
|
}
|
||||||
ratio, _ := strconv.Atoi(s.get(ctx, "pay.points_ratio"))
|
ratio, _ := strconv.Atoi(s.get(ctx, "pay.points_ratio"))
|
||||||
if ratio <= 0 {
|
if ratio <= 0 {
|
||||||
@@ -174,6 +174,7 @@ func (s *PaymentService) CreateOrder(ctx context.Context, user *model.User, amou
|
|||||||
Name: fmt.Sprintf("积分充值 %d", points),
|
Name: fmt.Sprintf("积分充值 %d", points),
|
||||||
Money: strconv.FormatFloat(amount, 'f', 2, 64),
|
Money: strconv.FormatFloat(amount, 'f', 2, 64),
|
||||||
NotifyURL: strings.TrimRight(notifyBase, "/") + "/admin/api/pay/notify",
|
NotifyURL: strings.TrimRight(notifyBase, "/") + "/admin/api/pay/notify",
|
||||||
|
ReturnURL: strings.TrimRight(notifyBase, "/") + "/settings",
|
||||||
ClientIP: clientIP,
|
ClientIP: clientIP,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -534,8 +534,8 @@ onMounted(() => { loadSite(); loadReg(); loadSmtp(); loadCredits(); loadAnnounce
|
|||||||
<input type="checkbox" v-model="pay.enabled" class="sw" />
|
<input type="checkbox" v-model="pay.enabled" class="sw" />
|
||||||
</label>
|
</label>
|
||||||
<label class="row">
|
<label class="row">
|
||||||
<span><span class="lbl">支付地址</span><span class="hint">易支付 API 根地址,自动拼 /mapi。</span></span>
|
<span><span class="lbl">支付地址</span><span class="hint">易支付站点根地址,自动拼 /mapi.php。</span></span>
|
||||||
<input v-model="pay.api_base" placeholder="https://pay.v8jisu.cn/api/pay" class="field !w-64" />
|
<input v-model="pay.api_base" placeholder="https://www.ezfpy.cn" class="field !w-64" />
|
||||||
</label>
|
</label>
|
||||||
<label class="row">
|
<label class="row">
|
||||||
<span><span class="lbl">商户ID (PID)</span></span>
|
<span><span class="lbl">商户ID (PID)</span></span>
|
||||||
|
|||||||
Reference in New Issue
Block a user