Feat: payjs payment

pull/247/head
HFO4 5 years ago
parent f8c14b3826
commit 0253b4e5b6

@ -25,6 +25,7 @@ require (
github.com/mojocn/base64Captcha v0.0.0-20190801020520-752b1cd608b2
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/pkg/errors v0.8.0
github.com/qingwg/payjs v0.0.0-20190928033402-c53dbe16b371
github.com/qiniu/api.v7/v7 v7.4.0
github.com/rafaeljusto/redigomock v0.0.0-20191117212112-00b2509252a1
github.com/robfig/cron/v3 v3.0.1

@ -160,6 +160,8 @@ github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/qingwg/payjs v0.0.0-20190928033402-c53dbe16b371 h1:8VWtyY2IwjEQZSNT4Kyyct9zv9hoegD5GQhFr+TMdCI=
github.com/qingwg/payjs v0.0.0-20190928033402-c53dbe16b371/go.mod h1:9UFrQveqNm3ELF6HSvMtDR3KYpJ7Ib9s0WVmYhaUBlU=
github.com/qiniu/api.v7/v7 v7.4.0 h1:9dZMVQifh31QGFLVaHls6akCaS2rlj3du8MnEFd7XjQ=
github.com/qiniu/api.v7/v7 v7.4.0/go.mod h1:VE5oC5rkE1xul0u1S2N0b2Uxq9/6hZzhyqjgK25XDcM=
github.com/quasoft/memstore v0.0.0-20180925164028-84a050167438 h1:jnz/4VenymvySjE+Ez511s0pqVzkUOmr1fwCVytNNWk=

@ -140,6 +140,8 @@ Neue',Helvetica,Arial,sans-serif; box-sizing: border-box; font-size: 14px; verti
{Name: "database_version", Value: `6`, Type: "version"},
{Name: "alipay_enabled", Value: `0`, Type: "payment"},
{Name: "payjs_enabled", Value: `0`, Type: "payment"},
{Name: "payjs_id", Value: ``, Type: "payment"},
{Name: "payjs_secret", Value: ``, Type: "payment"},
{Name: "appid", Value: ``, Type: "payment"},
{Name: "appkey", Value: ``, Type: "payment"},
{Name: "shopid", Value: ``, Type: "payment"},

@ -4,8 +4,10 @@ import (
"fmt"
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/qingwg/payjs"
"github.com/smartwalle/alipay/v3"
"math/rand"
"net/url"
"time"
)
@ -41,10 +43,9 @@ type Pay interface {
// OrderCreateRes 订单创建结果
type OrderCreateRes struct {
Payment bool `json:"payment"` // 是否需要支付
ID string `json:"id,omitempty"` // 订单号
QRCode string `json:"qr_code,omitempty"` // 支付二维码指向的地址
Redirect string `json:"redirect,omitempty"` // 支付跳转连接,和二维码二选一,不需要的留空
Payment bool `json:"payment"` // 是否需要支付
ID string `json:"id,omitempty"` // 订单号
QRCode string `json:"qr_code,omitempty"` // 支付二维码指向的地址
}
// NewPaymentInstance 获取新的支付实例
@ -71,6 +72,21 @@ func NewPaymentInstance(method string) (Pay, error) {
}
return &Alipay{Client: client}, nil
case "payjs":
options := model.GetSettingByNames("payjs_enabled", "payjs_secret", "payjs_id")
if options["payjs_enabled"] != "1" {
return nil, ErrUnknownPaymentMethod
}
callback, _ := url.Parse("/api/v3/callback/payjs")
payjsConfig := &payjs.Config{
Key: options["payjs_secret"],
MchID: options["payjs_id"],
NotifyUrl: model.GetSiteURL().ResolveReference(callback).String(),
}
return &PayJSClient{Client: payjs.New(payjsConfig)}, nil
default:
return nil, ErrUnknownPaymentMethod
}
@ -124,8 +140,8 @@ func NewOrder(pack *serializer.PackProduct, group *serializer.GroupProducts, num
}
func orderID() string {
return fmt.Sprintf("%s%d%d",
return fmt.Sprintf("%s%d",
time.Now().Format("20060102150405"),
10000+rand.Intn(90000),
time.Now().UnixNano())
100000+rand.Intn(900000),
)
}

@ -0,0 +1,31 @@
package payment
import (
model "github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/qingwg/payjs"
)
// PayJSClient PayJS支付处理
type PayJSClient struct {
Client *payjs.PayJS
}
// Create 创建订单
func (pay *PayJSClient) Create(order *model.Order, pack *serializer.PackProduct, group *serializer.GroupProducts, user *model.User) (*OrderCreateRes, error) {
if _, err := order.Create(); err != nil {
return nil, ErrInsertOrder.WithError(err)
}
PayNative := pay.Client.GetNative()
res, err := PayNative.Create(int64(order.Price*order.Num), order.Name, order.OrderNo, "", "")
if err != nil {
return nil, ErrIssueOrder.WithError(err)
}
return &OrderCreateRes{
Payment: true,
QRCode: res.CodeUrl,
ID: order.OrderNo,
}, nil
}

@ -5,6 +5,7 @@ import (
"github.com/HFO4/cloudreve/pkg/util"
"github.com/HFO4/cloudreve/service/vas"
"github.com/gin-gonic/gin"
"github.com/qingwg/payjs/notify"
"github.com/smartwalle/alipay/v3"
)
@ -100,3 +101,33 @@ func AlipayCallback(c *gin.Context) {
// 确认收到通知消息
alipay.AckNotification(c.Writer)
}
// PayJSCallback PayJS回调
func PayJSCallback(c *gin.Context) {
pay, err := payment.NewPaymentInstance("payjs")
if err != nil {
util.Log().Debug("[PayJS回调] 无法创建支付宝客户端, %s", err)
c.Status(400)
return
}
payNotify := pay.(*payment.PayJSClient).Client.GetNotify(c.Request, c.Writer)
//设置接收消息的处理方法
payNotify.SetMessageHandler(func(msg notify.Message) {
if err := payment.OrderPaid(msg.OutTradeNo); err != nil {
util.Log().Debug("[PayJS回调] 支付处理失败, %s", err)
}
})
//处理消息接收以及回复
err = payNotify.Serve()
if err != nil {
util.Log().Debug("[PayJS回调] 回调处理失败, %s", err)
return
}
//发送回复的消息
payNotify.SendResponseMsg()
}

@ -127,6 +127,11 @@ func InitMasterRouter() *gin.Engine {
// 回调接口
callback := v3.Group("callback")
{
// PAYJS回调
callback.POST(
"payjs",
controllers.PayJSCallback,
)
// 支付宝回调
callback.POST(
"alipay",

Loading…
Cancel
Save