feat: add callback
This commit is contained in:
@@ -1 +0,0 @@
|
|||||||
package http
|
|
||||||
50
backend/app/http/pays.go
Normal file
50
backend/app/http/pays.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package http
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"quyun/providers/wepay"
|
||||||
|
|
||||||
|
"github.com/go-pay/gopay"
|
||||||
|
"github.com/go-pay/gopay/wechat/v3"
|
||||||
|
"github.com/go-pay/util/js"
|
||||||
|
"github.com/gofiber/fiber/v3"
|
||||||
|
)
|
||||||
|
|
||||||
|
type pays struct {
|
||||||
|
wepay *wepay.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback
|
||||||
|
// @Router /pay/callback [get]
|
||||||
|
func (ctl *pays) Callback(ctx fiber.Ctx) error {
|
||||||
|
body := ctx.Body()
|
||||||
|
si := &wechat.SignInfo{
|
||||||
|
HeaderTimestamp: ctx.Get(wechat.HeaderTimestamp),
|
||||||
|
HeaderNonce: ctx.Get(wechat.HeaderNonce),
|
||||||
|
HeaderSignature: ctx.Get(wechat.HeaderSignature),
|
||||||
|
HeaderSerial: ctx.Get(wechat.HeaderSerial),
|
||||||
|
SignBody: string(body),
|
||||||
|
}
|
||||||
|
notifyReq := &wechat.V3NotifyReq{SignInfo: si}
|
||||||
|
if err := js.UnmarshalBytes(body, notifyReq); err != nil {
|
||||||
|
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": fmt.Sprintf("json unmarshal error:%v", err)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取微信平台证书
|
||||||
|
certMap := ctl.wepay.WxPublicKeyMap()
|
||||||
|
|
||||||
|
// 验证异步通知的签名
|
||||||
|
err := notifyReq.VerifySignByPKMap(certMap)
|
||||||
|
if err != nil {
|
||||||
|
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid signature"})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add process order job
|
||||||
|
|
||||||
|
return ctx.Status(http.StatusOK).JSON(&wechat.V3NotifyRsp{
|
||||||
|
Code: gopay.SUCCESS,
|
||||||
|
Message: "成功",
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"quyun/database/schemas/public/model"
|
"quyun/database/schemas/public/model"
|
||||||
"quyun/providers/wepay"
|
"quyun/providers/wepay"
|
||||||
|
|
||||||
|
"github.com/go-pay/gopay/wechat/v3"
|
||||||
"github.com/gofiber/fiber/v3"
|
"github.com/gofiber/fiber/v3"
|
||||||
"github.com/gofiber/fiber/v3/log"
|
"github.com/gofiber/fiber/v3/log"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -50,7 +51,7 @@ func (ctl *posts) Mine(ctx fiber.Ctx, pagination *requests.Pagination, query *Li
|
|||||||
// Buy
|
// Buy
|
||||||
// @Router /buy/:id [get]
|
// @Router /buy/:id [get]
|
||||||
// @Bind id path
|
// @Bind id path
|
||||||
func (ctl *posts) Buy(ctx fiber.Ctx, id int64) (*wepay.PrepayData, error) {
|
func (ctl *posts) Buy(ctx fiber.Ctx, id int64) (*wechat.JSAPIPayParams, error) {
|
||||||
var userId int64 = 1
|
var userId int64 = 1
|
||||||
|
|
||||||
user, err := models.Users.GetByID(ctx.Context(), userId)
|
user, err := models.Users.GetByID(ctx.Context(), userId)
|
||||||
@@ -80,5 +81,6 @@ func (ctl *posts) Buy(ctx fiber.Ctx, id int64) (*wepay.PrepayData, error) {
|
|||||||
log.Errorf("wepay.V3TransactionJsapi err: %v", err)
|
log.Errorf("wepay.V3TransactionJsapi err: %v", err)
|
||||||
return nil, errors.Wrap(err, "微信支付失败")
|
return nil, errors.Wrap(err, "微信支付失败")
|
||||||
}
|
}
|
||||||
return prePayResp, nil
|
|
||||||
|
return prePayResp.PaySignOfJSAPI()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"quyun/providers/wepay"
|
||||||
|
|
||||||
"go.ipao.vip/atom"
|
"go.ipao.vip/atom"
|
||||||
"go.ipao.vip/atom/container"
|
"go.ipao.vip/atom/container"
|
||||||
"go.ipao.vip/atom/contracts"
|
"go.ipao.vip/atom/contracts"
|
||||||
@@ -8,17 +10,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Provide(opts ...opt.Option) error {
|
func Provide(opts ...opt.Option) error {
|
||||||
if err := container.Container.Provide(func() (*posts, error) {
|
if err := container.Container.Provide(func(
|
||||||
obj := &posts{}
|
wepay *wepay.Client,
|
||||||
|
) (*posts, error) {
|
||||||
|
obj := &posts{
|
||||||
|
wepay: wepay,
|
||||||
|
}
|
||||||
|
|
||||||
return obj, nil
|
return obj, nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := container.Container.Provide(func(
|
if err := container.Container.Provide(func(
|
||||||
|
pays *pays,
|
||||||
posts *posts,
|
posts *posts,
|
||||||
) (contracts.HttpRoute, error) {
|
) (contracts.HttpRoute, error) {
|
||||||
obj := &Routes{
|
obj := &Routes{
|
||||||
|
pays: pays,
|
||||||
posts: posts,
|
posts: posts,
|
||||||
}
|
}
|
||||||
if err := obj.Prepare(); err != nil {
|
if err := obj.Prepare(); err != nil {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import (
|
|||||||
// @provider contracts.HttpRoute atom.GroupRoutes
|
// @provider contracts.HttpRoute atom.GroupRoutes
|
||||||
type Routes struct {
|
type Routes struct {
|
||||||
log *log.Entry `inject:"false"`
|
log *log.Entry `inject:"false"`
|
||||||
|
pays *pays
|
||||||
posts *posts
|
posts *posts
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +28,13 @@ func (r *Routes) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Routes) Register(router fiber.Router) {
|
func (r *Routes) Register(router fiber.Router) {
|
||||||
|
// 注册路由组: pays
|
||||||
|
router.Get("/pay/callback", Func0(
|
||||||
|
r.pays.Callback,
|
||||||
|
))
|
||||||
|
|
||||||
// 注册路由组: posts
|
// 注册路由组: posts
|
||||||
router.Get("/", DataFunc2(
|
router.Get("/posts", DataFunc2(
|
||||||
r.posts.List,
|
r.posts.List,
|
||||||
Query[requests.Pagination]("pagination"),
|
Query[requests.Pagination]("pagination"),
|
||||||
Query[ListQuery]("query"),
|
Query[ListQuery]("query"),
|
||||||
@@ -45,4 +51,9 @@ func (r *Routes) Register(router fiber.Router) {
|
|||||||
Query[ListQuery]("query"),
|
Query[ListQuery]("query"),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
router.Get("/buy/:id", DataFunc1(
|
||||||
|
r.posts.Buy,
|
||||||
|
PathParam[int64]("id"),
|
||||||
|
))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package wepay
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"crypto/rsa"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
@@ -55,11 +56,23 @@ func (c *Client) GetClient() *wechat.ClientV3 {
|
|||||||
return c.payClient
|
return c.payClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WxPublicKeyMap
|
||||||
|
func (c *Client) WxPublicKeyMap() map[string]*rsa.PublicKey {
|
||||||
|
return c.payClient.WxPublicKeyMap()
|
||||||
|
}
|
||||||
|
|
||||||
type PrepayData struct {
|
type PrepayData struct {
|
||||||
|
client *Client
|
||||||
|
|
||||||
AppID string `json:"app_id"`
|
AppID string `json:"app_id"`
|
||||||
PrepayID string `json:"prepay_id"`
|
PrepayID string `json:"prepay_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PaySignOfJSAPI
|
||||||
|
func (pay *PrepayData) PaySignOfJSAPI() (*wechat.JSAPIPayParams, error) {
|
||||||
|
return pay.client.payClient.PaySignOfJSAPI(pay.AppID, pay.PrepayID)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) V3TransactionJsapi(ctx context.Context, f func(*BodyMap)) (*PrepayData, error) {
|
func (c *Client) V3TransactionJsapi(ctx context.Context, f func(*BodyMap)) (*PrepayData, error) {
|
||||||
bm := NewBodyMap(c.config)
|
bm := NewBodyMap(c.config)
|
||||||
f(bm)
|
f(bm)
|
||||||
@@ -76,6 +89,8 @@ func (c *Client) V3TransactionJsapi(ctx context.Context, f func(*BodyMap)) (*Pre
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &PrepayData{
|
return &PrepayData{
|
||||||
|
client: c,
|
||||||
|
|
||||||
AppID: c.config.AppID,
|
AppID: c.config.AppID,
|
||||||
PrepayID: resp.Response.PrepayId,
|
PrepayID: resp.Response.PrepayId,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ func (s *WePayTestSuite) Test_PrePay() {
|
|||||||
})
|
})
|
||||||
So(err, ShouldBeNil)
|
So(err, ShouldBeNil)
|
||||||
So(resp, ShouldNotBeNil)
|
So(resp, ShouldNotBeNil)
|
||||||
|
|
||||||
s.T().Logf("prepay response: %+v", resp)
|
s.T().Logf("prepay response: %+v", resp)
|
||||||
|
|
||||||
|
sign, err := resp.PaySignOfJSAPI()
|
||||||
|
So(err, ShouldBeNil)
|
||||||
|
s.T().Logf("Sign: %+v", sign)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user