Initial commit
This commit is contained in:
commit
b0ebc38928
37
.github/workflows/buildx.yaml
vendored
Normal file
37
.github/workflows/buildx.yaml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: Buildx
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- latest
|
||||
tags:
|
||||
- 'v*'
|
||||
- 'release-*'
|
||||
- 'preview-*'
|
||||
|
||||
jobs:
|
||||
Pipline:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get REPO NAME
|
||||
run: echo "REPO_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Checkout code
|
||||
uses: https://git.linkiio.cn/actions/checkout@v3
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: https://git.linkiio.cn/actions/login-action@v2
|
||||
with:
|
||||
registry: docker.linkiio.cn
|
||||
username: ${{ vars.REGISTRY_USERNAME }}
|
||||
password: ${{ vars.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Build Push Docker imagee
|
||||
uses: https://git.linkiio.cn/actions/build-push-action@v3
|
||||
with:
|
||||
context: .
|
||||
file: https://open.linkiio.cn/docker/linkpay
|
||||
push: true
|
||||
tags: docker.linkiio.cn/linkpay/${{ env.REPO_NAME }}:${{ github.ref_name }}
|
||||
build-args: |
|
||||
GOPRIVATE=${{ secrets.GOPRIVATE }}
|
||||
NAME=${{ env.REPO_NAME }}
|
||||
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
!.gitignore
|
||||
.buildpath
|
||||
.hgignore.swp
|
||||
.project
|
||||
.orig
|
||||
.swp
|
||||
.idea/
|
||||
.settings/
|
||||
.vscode/
|
||||
bin/
|
||||
**/.DS_Store
|
||||
gf
|
||||
main
|
||||
main.exe
|
||||
hack*
|
||||
manifest
|
||||
output/
|
||||
temp/
|
||||
temp.yaml
|
||||
bin
|
||||
*.sum
|
||||
**/config/config.yaml
|
||||
|
||||
118
README.MD
Normal file
118
README.MD
Normal file
@ -0,0 +1,118 @@
|
||||
# Linkpay Grpc Service
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
This is the grpc service for Linkpay.
|
||||
## Directory Structure
|
||||
```
|
||||
├── api //api预留
|
||||
├── config //配置文件
|
||||
│ └── config.toml
|
||||
├── internal //应用实现
|
||||
│ ├── cmd
|
||||
│ │ └── cmd.go
|
||||
│ ├── consts //常量/结构定义
|
||||
│ │ └── consts.go
|
||||
│ ├── controller //控制层
|
||||
│ │ └── api
|
||||
│ │ └── api.go
|
||||
│ ├── logic //逻辑层(主要业务代码实现)
|
||||
│ │ ├── event.go //回调逻辑实现
|
||||
│ │ ├── pay.go //支付逻辑实现
|
||||
│ │ ├── ping.go //碰撞测试
|
||||
│ │ ├── query.go //查询逻辑实现
|
||||
│ │ └── refund.go //退款逻辑实现
|
||||
│ │ └── revoke.go //撤销逻辑实现
|
||||
│ ├── packed //三方包
|
||||
│ │ ├── packed.go
|
||||
│ │ └── unarymeta.go
|
||||
│ └── service //服务层
|
||||
│ ├── grpc.go
|
||||
│ └── request.go
|
||||
├── main.go //入口
|
||||
```
|
||||
|
||||
### 启动项目
|
||||
```
|
||||
go get -u && go run .
|
||||
```
|
||||
|
||||
### 调试说明
|
||||
|
||||
|
||||
|
||||
下载postman工具: https://www.postman.com/downloads/
|
||||
|
||||
postman调试操作:
|
||||
- 新建grpc接口。
|
||||
- 在url中输入:127.0.0.1:9901 即可
|
||||
- 在logic逻辑层实现各接口能力。
|
||||
|
||||
### 接口要求实现
|
||||
- 回调 event 需要返回回调结果
|
||||
- 碰撞测试 ping 需要返回pong/或当前时间戳
|
||||
- 创建支付 pay 需要返回支付订单信息
|
||||
- 查询支付 query 需要返回支付/退单的订单的状态信息
|
||||
- 退款 refund 需要返回退款订单信息
|
||||
- 撤销 revoke 需要返回撤销订单信息
|
||||
|
||||
### 回调说明
|
||||
- 回调接口需要返回回调结果,包括成功或失败,及相关信息。
|
||||
- 入口数据, req *protobuf.CallbackReq, 其中包含第三方的URL、Header、Body等信息。
|
||||
|
||||
- 返回数据, res *protobuf.Orders, 其中包含订单状态、订单号、订单金额等信息。尽可能的满足字段信息都需要返回。
|
||||
其中Response字段为回调接口返回的原始数据,方便业务层处理日志。
|
||||
|
||||
|
||||
```go
|
||||
func Callback(ctx context.Context, req *protobuf.CallbackReq) (res *protobuf.Orders, err error) {
|
||||
|
||||
res = &protobuf.Orders{
|
||||
Kid: req.Kid, //商户ID
|
||||
Uid: req.Uid, //用户ID
|
||||
Org: req.Org, //商户名称
|
||||
Via: req.Via, //支付渠道
|
||||
OrgNo: "12345", //渠道订单号
|
||||
OrderNo: "67890", //商户订单号
|
||||
Response: string(req.GetBody()), //解签后的Body数据
|
||||
State: -1, //订单状态 (参考 protobuf.State 枚举)
|
||||
StateText: "支付失败", //订单状态原因,状态说明
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
### 通用API请求方法
|
||||
service/request.go
|
||||
|
||||
```go
|
||||
//请求API
|
||||
r, err := service.Request(ctx).Header("Authorization", "{Token}").Post("/v1/pay/create", req)
|
||||
|
||||
//返回支付结果
|
||||
res = &protobuf.Orders{
|
||||
Response: r.ReadAllString(),
|
||||
}
|
||||
```
|
||||
|
||||
该方法封装了请求的通用方法,包括:
|
||||
- Header:设置请求头
|
||||
- Post:发起post请求
|
||||
- Get:发起get请求
|
||||
|
||||
其中多个Header头示例
|
||||
```go
|
||||
r, err := service.Request(ctx).Header("x-api-key", "{Token}").Header("x-api-secret", "{Secret}").Post("/v1/pay/create", req)
|
||||
```
|
||||
|
||||
r 方便获取各类HTTP响应信息,数据。
|
||||
|
||||
### 日志说明
|
||||
请严格遵守Goframe日志规范打印
|
||||
如:
|
||||
```go
|
||||
g.Log("业务模块").Info(ctx, "this is a info log")
|
||||
g.Log("pay").Error(ctx, "this is a pay error log")
|
||||
```
|
||||
4
config/api.yml
Normal file
4
config/api.yml
Normal file
@ -0,0 +1,4 @@
|
||||
#渠道API信息
|
||||
url: https://api.xxpay.com
|
||||
key: xxpay_api_key
|
||||
secret: xxpay_api_secret
|
||||
12
config/config.toml
Normal file
12
config/config.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[app]
|
||||
env="dev"
|
||||
|
||||
[grpc]
|
||||
name="org"
|
||||
address=":9901"
|
||||
|
||||
|
||||
[logger]
|
||||
level="all"
|
||||
stdout=true
|
||||
|
||||
54
go.mod
Normal file
54
go.mod
Normal file
@ -0,0 +1,54 @@
|
||||
module linkpay
|
||||
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
git.linkiio.cn/linkpay/invoke v1.4.4
|
||||
git.linkiio.cn/linkpay/protobuf v1.5.3
|
||||
github.com/gogf/gf/contrib/rpc/grpcx/v2 v2.9.0
|
||||
github.com/gogf/gf/v2 v2.9.0
|
||||
google.golang.org/grpc v1.74.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/coreos/go-semver v0.3.1 // indirect
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogf/gf/contrib/registry/etcd/v2 v2.9.0 // indirect
|
||||
github.com/gogf/gf/contrib/registry/file/v2 v2.9.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.6.4 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.6.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
20
internal/cmd/cmd.go
Normal file
20
internal/cmd/cmd.go
Normal file
@ -0,0 +1,20 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/controller/api"
|
||||
|
||||
"git.linkiio.cn/linkpay/invoke/grpcx"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gcmd"
|
||||
)
|
||||
|
||||
var (
|
||||
Main = gcmd.Command{
|
||||
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
|
||||
s := grpcx.Registry(api.Register)
|
||||
s.Run()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
)
|
||||
1
internal/consts/consts.go
Normal file
1
internal/consts/consts.go
Normal file
@ -0,0 +1 @@
|
||||
package consts
|
||||
45
internal/controller/api/api.go
Normal file
45
internal/controller/api/api.go
Normal file
@ -0,0 +1,45 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/logic"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/contrib/rpc/grpcx/v2"
|
||||
)
|
||||
|
||||
type Controller struct {
|
||||
protobuf.UnimplementedOrgServer
|
||||
}
|
||||
|
||||
func Register(s *grpcx.GrpcServer) {
|
||||
protobuf.RegisterOrgServer(s.Server, &Controller{})
|
||||
}
|
||||
|
||||
func (*Controller) Event(ctx context.Context, req *protobuf.EventReq) (res *protobuf.EventRes, err error) {
|
||||
return logic.Event(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) Ping(ctx context.Context, req *protobuf.PingReq) (res *protobuf.PongRes, err error) {
|
||||
return logic.Ping(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) Pay(ctx context.Context, req *protobuf.PayReq) (res *protobuf.Orders, err error) {
|
||||
return logic.Pay(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) Refund(ctx context.Context, req *protobuf.RefundReq) (res *protobuf.Refunds, err error) {
|
||||
return logic.Refund(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) Revoke(ctx context.Context, req *protobuf.RefundReq) (res *protobuf.Refunds, err error) {
|
||||
return logic.Revoke(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) QueryOrder(ctx context.Context, req *protobuf.QueryReq) (res *protobuf.Orders, err error) {
|
||||
return logic.QueryOrder(ctx, req)
|
||||
}
|
||||
|
||||
func (*Controller) QueryRefund(ctx context.Context, req *protobuf.QueryReq) (res *protobuf.Refunds, err error) {
|
||||
return logic.QueryRefund(ctx, req)
|
||||
}
|
||||
41
internal/logic/demo.go
Normal file
41
internal/logic/demo.go
Normal file
@ -0,0 +1,41 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/service"
|
||||
"log"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
)
|
||||
|
||||
/*
|
||||
*
|
||||
- 双向通信流示例查询订单
|
||||
- @param void
|
||||
- @author dc.To
|
||||
- @version 20250429
|
||||
- ApiOrders(ctx, &protobuf.Orders{
|
||||
Org: "org",
|
||||
})
|
||||
*/
|
||||
func ApiOrders(ctx context.Context, req *protobuf.Orders) {
|
||||
|
||||
client := service.BssClient()
|
||||
|
||||
stream, _ := client.Order(context.Background())
|
||||
|
||||
//查询协程
|
||||
go func() {
|
||||
stream.Send(req)
|
||||
stream.CloseSend()
|
||||
}()
|
||||
|
||||
//监听返回
|
||||
for {
|
||||
res, err := stream.Recv()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
log.Printf("Got order response: %v", res)
|
||||
}
|
||||
}
|
||||
34
internal/logic/event.go
Normal file
34
internal/logic/event.go
Normal file
@ -0,0 +1,34 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/service"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
)
|
||||
|
||||
/**
|
||||
* 回调事件实现
|
||||
* @author dc.To
|
||||
* @version 20250418
|
||||
*/
|
||||
func Event(ctx context.Context, req *protobuf.EventReq) (res *protobuf.EventRes, err error) {
|
||||
|
||||
res = &protobuf.EventRes{
|
||||
Type: "order",
|
||||
Data: &protobuf.EventRes_Order{
|
||||
Order: &protobuf.Orders{
|
||||
Kid: req.Kid, //商户ID
|
||||
Uid: req.Uid, //用户ID
|
||||
Org: req.Org, //商户名称
|
||||
Via: req.Via, //支付渠道
|
||||
OrgNo: "12345", //渠道订单号
|
||||
OrderNo: "67890", //商户订单号
|
||||
Response: string(req.GetBody()), //解签后的Body数据
|
||||
State: int32(service.GetState("error")), //订单状态 (参考 protobuf.State 枚举 @see https://git.linkiio.cn/linkpay/protobuf/src/commit/982698cc1cf9d050d21f904563b5403d1f11d987/org.pb.go#L26)
|
||||
StateText: "支付失败", //渠道方状态原因,状态说明
|
||||
},
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
64
internal/logic/event_test.go
Normal file
64
internal/logic/event_test.go
Normal file
@ -0,0 +1,64 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/service"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/v2/encoding/gbase64"
|
||||
"github.com/gogf/gf/v2/encoding/gjson"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"google.golang.org/grpc/metadata"
|
||||
)
|
||||
|
||||
func Config(ctx context.Context) *gjson.Json {
|
||||
md, ok := metadata.FromIncomingContext(ctx)
|
||||
|
||||
if !ok {
|
||||
return &gjson.Json{}
|
||||
}
|
||||
|
||||
c := md.Get("x-cfg-api")
|
||||
b, _ := gbase64.DecodeString(c[0])
|
||||
return gjson.New(b)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 回调事件实现
|
||||
* @author dc.To
|
||||
* @version 20250418
|
||||
*/
|
||||
func EventTestCase(ctx context.Context, req *protobuf.EventReq) (res *protobuf.EventRes, err error) {
|
||||
|
||||
if req.Kid != Config(ctx).Get("appId").Uint64() || req.Kid != g.Cfg("api").MustGet(ctx, "appId").Uint64() {
|
||||
g.Log().Errorf(ctx, "req-Kid: %d == grpc-Kid: %d == cfg-Kid: %d", req.Kid, Config(ctx).Get("appId").Uint64(), g.Cfg("api").MustGet(ctx, "appId").Uint64())
|
||||
return nil, gerror.NewCodef(gcode.CodeInternalError, "req-Kid [%d] not match Grpc Kid [%d] or cfg-Kid [%d]", req.Kid, Config(ctx).Get("appId").Uint64(), g.Cfg("api").MustGet(ctx, "appId").Uint64())
|
||||
} else {
|
||||
g.Log().Infof(ctx, "req-Kid: %d == grpc-Kid: %d == cfg-Kid: %d", req.Kid, Config(ctx).Get("appId").Uint64(), g.Cfg("api").MustGet(ctx, "appId").Uint64())
|
||||
}
|
||||
|
||||
return &protobuf.EventRes{
|
||||
Body: Config(ctx).Get("appId").String(),
|
||||
}, nil
|
||||
|
||||
res = &protobuf.EventRes{
|
||||
Type: "order",
|
||||
Data: &protobuf.EventRes_Order{
|
||||
Order: &protobuf.Orders{
|
||||
Kid: req.Kid, //商户ID
|
||||
Uid: req.Uid, //用户ID
|
||||
Org: req.Org, //商户名称
|
||||
Via: req.Via, //支付渠道
|
||||
OrgNo: "12345", //渠道订单号
|
||||
OrderNo: "67890", //商户订单号
|
||||
Response: string(req.GetBody()), //解签后的Body数据
|
||||
State: int32(service.GetState("error")), //订单状态 (参考 protobuf.State 枚举 @see https://git.linkiio.cn/linkpay/protobuf/src/commit/982698cc1cf9d050d21f904563b5403d1f11d987/org.pb.go#L26)
|
||||
StateText: "支付失败", //渠道方状态原因,状态说明
|
||||
},
|
||||
},
|
||||
}
|
||||
return
|
||||
}
|
||||
21
internal/logic/pay.go
Normal file
21
internal/logic/pay.go
Normal file
@ -0,0 +1,21 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"linkpay/internal/service"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
)
|
||||
|
||||
func Pay(ctx context.Context, req *protobuf.PayReq) (res *protobuf.Orders, err error) {
|
||||
|
||||
//测试请求API
|
||||
r, err := service.Request(ctx).Header("Authorization", "{Token}").ContentType("application/json").Post("", req)
|
||||
|
||||
//返回支付结果
|
||||
res = &protobuf.Orders{
|
||||
Response: r.ReadAllString(),
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
13
internal/logic/ping.go
Normal file
13
internal/logic/ping.go
Normal file
@ -0,0 +1,13 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func Ping(ctx context.Context, req *protobuf.PingReq) (res *protobuf.PongRes, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
17
internal/logic/query.go
Normal file
17
internal/logic/query.go
Normal file
@ -0,0 +1,17 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func QueryOrder(ctx context.Context, req *protobuf.QueryReq) (res *protobuf.Orders, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
|
||||
func QueryRefund(ctx context.Context, req *protobuf.QueryReq) (res *protobuf.Refunds, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
13
internal/logic/refund.go
Normal file
13
internal/logic/refund.go
Normal file
@ -0,0 +1,13 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func Refund(ctx context.Context, req *protobuf.RefundReq) (res *protobuf.Refunds, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
13
internal/logic/revoke.go
Normal file
13
internal/logic/revoke.go
Normal file
@ -0,0 +1,13 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
)
|
||||
|
||||
func Revoke(ctx context.Context, req *protobuf.RefundReq) (res *protobuf.Refunds, err error) {
|
||||
return nil, gerror.NewCode(gcode.CodeNotImplemented)
|
||||
}
|
||||
1
internal/packed/packed.go
Normal file
1
internal/packed/packed.go
Normal file
@ -0,0 +1 @@
|
||||
package packed
|
||||
15
internal/service/grpc.go
Normal file
15
internal/service/grpc.go
Normal file
@ -0,0 +1,15 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"git.linkiio.cn/linkpay/protobuf"
|
||||
"git.linkiio.cn/linkpay/invoke/grpcx"
|
||||
)
|
||||
|
||||
/**
|
||||
* BSS 双向通信流
|
||||
* @author dc.To
|
||||
* @version 20250410
|
||||
*/
|
||||
func BssClient() protobuf.BssClient {
|
||||
return grpcx.BssClient()
|
||||
}
|
||||
91
internal/service/request.go
Normal file
91
internal/service/request.go
Normal file
@ -0,0 +1,91 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/gclient"
|
||||
)
|
||||
|
||||
type RequestContext struct {
|
||||
*gclient.Client
|
||||
context.Context
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一API请求方法
|
||||
* @param void
|
||||
* @author dc.To
|
||||
* @version 20250313
|
||||
*/
|
||||
func Request(ctx context.Context) *RequestContext {
|
||||
|
||||
c := &RequestContext{
|
||||
Client: gclient.New(),
|
||||
Context: ctx,
|
||||
}
|
||||
|
||||
url, err := g.Cfg("api").Get(ctx, "url")
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, "Api url not found in config file: ", err.Error())
|
||||
}
|
||||
|
||||
c.SetPrefix(url.String())
|
||||
c.SetContentType("application/json")
|
||||
c.Use(handle)
|
||||
return c
|
||||
}
|
||||
|
||||
func (r *RequestContext) Header(k, v string) *RequestContext {
|
||||
r.SetHeader(k, v)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *RequestContext) ContentType(t string) *RequestContext {
|
||||
r.SetContentType(t)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *RequestContext) Get(path string, data interface{}) (*gclient.Response, error) {
|
||||
return r.Client.Get(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) Post(path string, data interface{}) (*gclient.Response, error) {
|
||||
return r.Client.Post(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) GetVar(path string, data interface{}) *g.Var {
|
||||
return r.Client.GetVar(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) PostVar(path string, data interface{}) *g.Var {
|
||||
return r.Client.PostVar(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) GetBytes(path string, data interface{}) []byte {
|
||||
return r.Client.GetBytes(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) PostBytes(path string, data interface{}) []byte {
|
||||
return r.Client.PostBytes(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) GetContent(path string, data interface{}) string {
|
||||
return r.Client.GetContent(r.Context, path, data)
|
||||
}
|
||||
|
||||
func (r *RequestContext) PostContent(path string, data interface{}) string {
|
||||
return r.Client.PostContent(r.Context, path, data)
|
||||
}
|
||||
|
||||
func handle(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) {
|
||||
resp, err = c.Next(r)
|
||||
|
||||
if os.Getenv("APP_ENV") == "dev" {
|
||||
resp.RawDump()
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
||||
25
internal/service/state.go
Normal file
25
internal/service/state.go
Normal file
@ -0,0 +1,25 @@
|
||||
package service
|
||||
|
||||
import "git.linkiio.cn/linkpay/protobuf"
|
||||
|
||||
/**
|
||||
* 返回状态 参考 protobuf.State 枚举
|
||||
* 本方法做为示例,实际业务中,根据渠道返回状态时,需要根据具体情况进行判断和转换
|
||||
* @see https://git.linkiio.cn/linkpay/protobuf/src/commit/982698cc1cf9d050d21f904563b5403d1f11d987/org.pb.go#L26
|
||||
* @param void
|
||||
* @author dc.To
|
||||
* @version 20250425
|
||||
*/
|
||||
func GetState(orgState interface{}) protobuf.State {
|
||||
|
||||
var state = protobuf.State_Pending
|
||||
|
||||
//当渠道终态 成功时,状态为成功
|
||||
if orgState == "success" {
|
||||
state = protobuf.State_Success
|
||||
} else if orgState == "failed" {
|
||||
state = protobuf.State_Failure
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user