-
Notifications
You must be signed in to change notification settings - Fork 2
/
alipay.go
146 lines (130 loc) 路 3 KB
/
alipay.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
Copyright 2020 RS4
@Author: Weny Xu
@Date: 2021/01/07 4:20
*/
package alipay
import (
"context"
"github.com/WenyXu/better-alipay-go/config"
m "github.com/WenyXu/better-alipay-go/m"
"github.com/WenyXu/better-alipay-go/options"
)
type Service interface {
Options() options.Options
Request(method string, param m.M, response interface{}, opts ...options.Option) (err error)
MakeParam(method string, param m.M, opts ...options.Option) (data m.M, err error)
}
type service struct {
opts options.Options
}
// MakeParam
func (s service) MakeParam(method string, param m.M, opts ...options.Option) (data m.M, err error) {
copyOpts := s.opts.Copy()
// setup options
for _, o := range opts {
o(©Opts)
}
result := make(m.M)
err = m.CombineMakeMapEndpointFunc(
config.SetMethod(method),
config.SetPublicParam(copyOpts.Config),
config.SetOptionalParam(copyOpts.Config),
config.SetBizContent(param),
config.SignParam(copyOpts.Config),
)(result)
if err != nil {
return nil, err
}
return result, nil
}
// Do Request
func (s service) Request(method string, param m.M, response interface{}, opts ...options.Option) (err error) {
copyOpts := s.opts.Copy()
ctx, cancel := context.WithCancel(copyOpts.Context)
defer cancel()
// setup options
for _, o := range opts {
o(©Opts)
}
// make request
req, err := copyOpts.MakeReq(ctx, method, param, copyOpts.Config)
if err != nil {
cancel()
return err
}
// before hooks
for _, f := range copyOpts.Before {
ctx = f(ctx, req)
}
// do request
resp, err := copyOpts.Transport.RoundTrip(req)
if err != nil {
cancel()
return err
}
defer resp.Body.Close()
// after hooks
for _, f := range copyOpts.After {
ctx = f(ctx, resp)
}
// dec response
err = copyOpts.Dec(ctx, resp, response)
if err != nil {
cancel()
return err
}
return
}
// Options
func (s service) Options() options.Options {
return s.opts
}
// New will return a empty service, using global default configurations
//
// you can use:
//
// options.SetDefaultTransport(f http.RoundTripper)
//
// options.SetDefaultDecFunc(f DecFunc)
//
// options.SetDefaultMakeReqFunc(f MakeReqFunc)
//
// options.SetDefaultLogger(f logger.Logger)
//
// options.SetDefaultLocation(f Option)
//
// To modify default global configurations.
//
// opt := Options{
// Transport: DefaultTransport,
// Context: context.Background(),
// MakeReq: DefaultMakeReqFunc,
// Dec: DefaultDecFunc,
// Logger: DefaultLogger,
// }
func New(opts ...options.Option) Service {
return newService(func(s *service) {
s.opts = options.NewOptions(opts...)
})
}
// Default return a default service
//
// s := Default()
// // same as
// s := New(
// options.DefaultLocation,
// options.DefaultCharset(),
// options.DefaultFormat(),
// options.DefaultVersion(),
// )
func Default(opts ...options.Option) Service {
return newService(func(s *service) {
s.opts = options.DefaultOptions(opts...)
})
}
func newService(setup func(s *service)) Service {
s := &service{}
setup(s)
return s
}