mirror of
https://github.com/halejohn/Cloudreve.git
synced 2026-01-26 09:34:57 +08:00
Feat: vas alipay
This commit is contained in:
42
pkg/payment/alipay.go
Normal file
42
pkg/payment/alipay.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
model "github.com/HFO4/cloudreve/models"
|
||||
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||
alipay "github.com/smartwalle/alipay/v3"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// Alipay 支付宝当面付支付处理
|
||||
type Alipay struct {
|
||||
Client *alipay.Client
|
||||
}
|
||||
|
||||
// Create 创建订单
|
||||
func (pay *Alipay) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
|
||||
gateway, _ := url.Parse("/api/v3/callback/alipay")
|
||||
var p = alipay.TradePreCreate{
|
||||
Trade: alipay.Trade{
|
||||
NotifyURL: model.GetSiteURL().ResolveReference(gateway).String(),
|
||||
Subject: order.Name,
|
||||
OutTradeNo: order.OrderNo,
|
||||
TotalAmount: fmt.Sprintf("%.2f", float64(order.Price*order.Num)/100),
|
||||
},
|
||||
}
|
||||
|
||||
if _, err := order.Create(); err != nil {
|
||||
return nil, ErrInsertOrder.WithError(err)
|
||||
}
|
||||
|
||||
res, err := pay.Client.TradePreCreate(p)
|
||||
if err != nil {
|
||||
return nil, ErrIssueOrder.WithError(err)
|
||||
}
|
||||
|
||||
return &OrderCreateRes{
|
||||
Payment: true,
|
||||
QRCode: res.Content.QRCode,
|
||||
ID: order.OrderNo,
|
||||
}, nil
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import (
|
||||
"fmt"
|
||||
model "github.com/HFO4/cloudreve/models"
|
||||
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -23,6 +26,12 @@ var (
|
||||
ErrGroupInvalid = serializer.NewError(serializer.CodeNoPermissionErr, "用户组不可用", nil)
|
||||
// ErrUpgradeGroup 用户组冲突
|
||||
ErrUpgradeGroup = serializer.NewError(serializer.CodeDBError, "无法升级用户组", nil)
|
||||
// ErrUInitPayment 无法初始化支付实例
|
||||
ErrUInitPayment = serializer.NewError(serializer.CodeInternalSetting, "无法初始化支付实例", nil)
|
||||
// ErrIssueOrder 订单接口请求失败
|
||||
ErrIssueOrder = serializer.NewError(serializer.CodeInternalSetting, "无法创建订单", nil)
|
||||
// ErrOrderNotFound 订单不存在
|
||||
ErrOrderNotFound = serializer.NewError(serializer.CodeNotFound, "订单不存在", nil)
|
||||
)
|
||||
|
||||
// Pay 支付处理接口
|
||||
@@ -32,16 +41,39 @@ type Pay interface {
|
||||
|
||||
// OrderCreateRes 订单创建结果
|
||||
type OrderCreateRes struct {
|
||||
Payment bool `json:"payment"` // 是否需要支付
|
||||
Payment bool `json:"payment"` // 是否需要支付
|
||||
ID string `json:"id,omitempty"` // 订单号
|
||||
QRCode string `json:"qr_code,omitempty"` // 支付二维码指向的地址
|
||||
Redirect string `json:"redirect,omitempty"` // 支付跳转连接,和二维码二选一,不需要的留空
|
||||
}
|
||||
|
||||
// NewPaymentInstance 获取新的支付实例
|
||||
func NewPaymentInstance(method string) (Pay, error) {
|
||||
if method == "score" {
|
||||
switch method {
|
||||
case "score":
|
||||
return &ScorePayment{}, nil
|
||||
}
|
||||
case "alipay":
|
||||
options := model.GetSettingByNames("alipay_enabled", "appid", "appkey", "shopid")
|
||||
if options["alipay_enabled"] != "1" {
|
||||
return nil, ErrUnknownPaymentMethod
|
||||
}
|
||||
|
||||
return nil, ErrUnknownPaymentMethod
|
||||
// 初始化支付宝客户端
|
||||
var client, err = alipay.New(options["appid"], options["appkey"], true)
|
||||
if err != nil {
|
||||
return nil, ErrUInitPayment.WithError(err)
|
||||
}
|
||||
|
||||
// 加载支付宝公钥
|
||||
err = client.LoadAliPayPublicKey(options["shopid"])
|
||||
if err != nil {
|
||||
return nil, ErrUInitPayment.WithError(err)
|
||||
}
|
||||
|
||||
return &Alipay{Client: client}, nil
|
||||
default:
|
||||
return nil, ErrUnknownPaymentMethod
|
||||
}
|
||||
}
|
||||
|
||||
// NewOrder 创建新订单
|
||||
@@ -78,6 +110,7 @@ func NewOrder(pack *serializer.PackProduct, group *serializer.GroupProducts, num
|
||||
// 创建订单记录
|
||||
order := &model.Order{
|
||||
UserID: user.ID,
|
||||
OrderNo: orderID(),
|
||||
Type: orderType,
|
||||
Method: method,
|
||||
ProductID: productID,
|
||||
@@ -89,3 +122,10 @@ func NewOrder(pack *serializer.PackProduct, group *serializer.GroupProducts, num
|
||||
|
||||
return pay.Create(order, pack, group, user)
|
||||
}
|
||||
|
||||
func orderID() string {
|
||||
return fmt.Sprintf("%s%d%d",
|
||||
time.Now().Format("20060102150405"),
|
||||
10000+rand.Intn(90000),
|
||||
time.Now().UnixNano())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
model "github.com/HFO4/cloudreve/models"
|
||||
"github.com/HFO4/cloudreve/pkg/serializer"
|
||||
"time"
|
||||
@@ -69,3 +71,58 @@ func GiveProduct(user *model.User, pack *serializer.PackProduct, group *serializ
|
||||
return GiveScore(user, num)
|
||||
}
|
||||
}
|
||||
|
||||
// OrderPaid 订单已支付处理
|
||||
func OrderPaid(orderNo string) error {
|
||||
order, err := model.GetOrderByNo(orderNo)
|
||||
if err != nil {
|
||||
return ErrOrderNotFound.WithError(err)
|
||||
}
|
||||
|
||||
// 更新订单状态为 已支付
|
||||
order.UpdateStatus(model.OrderPaid)
|
||||
|
||||
user, err := model.GetActiveUserByID(order.UserID)
|
||||
if err != nil {
|
||||
return errors.New("用户不存在")
|
||||
}
|
||||
|
||||
// 查询商品
|
||||
options := model.GetSettingByNames("pack_data", "group_sell_data")
|
||||
|
||||
var (
|
||||
packs []serializer.PackProduct
|
||||
groups []serializer.GroupProducts
|
||||
)
|
||||
if err := json.Unmarshal([]byte(options["pack_data"]), &packs); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal([]byte(options["group_sell_data"]), &groups); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找要购买的商品
|
||||
var (
|
||||
pack *serializer.PackProduct
|
||||
group *serializer.GroupProducts
|
||||
)
|
||||
if order.Type == model.GroupOrderType {
|
||||
for _, v := range groups {
|
||||
if v.ID == order.ProductID {
|
||||
group = &v
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if order.Type == model.PackOrderType {
|
||||
for _, v := range packs {
|
||||
if v.ID == order.ProductID {
|
||||
pack = &v
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// "发货"
|
||||
return GiveProduct(&user, pack, group, order.Num)
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user