Skip to content

Commit 6dabb39

Browse files
authored
Merge pull request #643 from ywanbing/feat_pay_notify
Feat pay notify
2 parents 9b3a8ed + 9415f7d commit 6dabb39

File tree

6 files changed

+230
-11
lines changed

6 files changed

+230
-11
lines changed

src/payment/notify/custom.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package notify
2+
3+
import (
4+
"io"
5+
"net/http"
6+
7+
"github.com/ArtisanCloud/PowerLibs/v3/object"
8+
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
9+
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
10+
)
11+
12+
// CustomNotify 框架内没有实现的,可以使用这个自己实现
13+
type CustomNotify[T any] struct {
14+
*CustomHandler
15+
}
16+
17+
func NewCustomNotify[T any](app kernel.ApplicationPaymentInterface, body io.Reader) *CustomNotify[T] {
18+
return &CustomNotify[T]{
19+
NewCustomHandler(app, body),
20+
}
21+
}
22+
23+
func (comp *CustomNotify[T]) Handle(closure func(message *request.RequestNotify, transaction *T, fail func(message string)) interface{}) (*http.Response, error) {
24+
message, err := comp.GetMessage()
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
reqInfo, err := comp.reqInfo()
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
// struct the content
35+
var transaction = new(T)
36+
err = object.JsonDecode([]byte(reqInfo), transaction)
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
result := closure(message, transaction, comp.Fail)
42+
comp.Strict(result)
43+
44+
return comp.ToResponse()
45+
}

src/payment/notify/custom_handler.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package notify
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"errors"
7+
"fmt"
8+
"io"
9+
"net/http"
10+
11+
"github.com/ArtisanCloud/PowerLibs/v3/object"
12+
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/support"
13+
base2 "github.com/ArtisanCloud/PowerWeChat/v3/src/payment/base"
14+
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
15+
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
16+
)
17+
18+
type CustomHandler struct {
19+
App kernel.ApplicationPaymentInterface
20+
Message *request.RequestNotify
21+
fail string
22+
Attributes *object.StringMap
23+
Check bool
24+
Sign bool
25+
26+
ExternalBody io.Reader
27+
28+
// Handle func(closure func(message *request.RequestNotify, transaction *models.Transaction, fail func(groupWelcomeTemplate string)) interface{}) *http.Response
29+
}
30+
31+
func NewCustomHandler(app kernel.ApplicationPaymentInterface, body io.Reader) *CustomHandler {
32+
33+
// -------------- external request --------------
34+
var req io.Reader = &bytes.Buffer{}
35+
if body != nil {
36+
req = body
37+
}
38+
39+
return &CustomHandler{
40+
App: app,
41+
Check: true,
42+
Sign: false,
43+
ExternalBody: req,
44+
}
45+
}
46+
47+
func (handler *CustomHandler) Fail(message string) {
48+
handler.fail = message
49+
}
50+
51+
func (handler *CustomHandler) RespondWith(attributes *object.StringMap, sign bool) *CustomHandler {
52+
53+
handler.Attributes = attributes
54+
handler.Sign = sign
55+
56+
return handler
57+
}
58+
func (handler *CustomHandler) ToResponse() (response *http.Response, err error) {
59+
60+
returnCode := SUCCESS
61+
returnMsg := "成功"
62+
if handler.fail != "" {
63+
returnCode = FAIL
64+
returnMsg = handler.fail
65+
err = errors.New(handler.fail)
66+
}
67+
base := &object.StringMap{
68+
"code": returnCode,
69+
"uniformMessage": returnMsg,
70+
}
71+
72+
attributes := object.MergeStringMap(base, handler.Attributes)
73+
baseClient := (handler.App).GetComponent("Base").(*base2.Client)
74+
if handler.Sign {
75+
(*attributes)["sign"], err = baseClient.BaseClient.Signer.GenerateSign("")
76+
if err != nil {
77+
return nil, err
78+
}
79+
}
80+
81+
bodyBuffer, _ := json.Marshal(attributes)
82+
rs := &http.Response{
83+
StatusCode: http.StatusOK,
84+
}
85+
rs.Body = io.NopCloser(bytes.NewBuffer(bodyBuffer))
86+
87+
return rs, err
88+
}
89+
90+
func (handler *CustomHandler) GetMessage() (notify *request.RequestNotify, err error) {
91+
92+
if handler.Message != nil {
93+
return handler.Message, nil
94+
}
95+
96+
body := handler.ExternalBody
97+
98+
requestBody, err := io.ReadAll(body)
99+
if err != nil {
100+
return nil, err
101+
}
102+
handler.Message = &request.RequestNotify{}
103+
err = object.JsonDecode(requestBody, handler.Message)
104+
if err != nil {
105+
return nil, err
106+
}
107+
108+
// note: 自定义的不保存 http request
109+
// handler.Message.RawRequest = body
110+
111+
return handler.Message, nil
112+
}
113+
114+
func (handler *CustomHandler) DecryptMessage() (string, error) {
115+
message, err := handler.GetMessage()
116+
if err != nil {
117+
return "", err
118+
}
119+
if message.Resource == nil {
120+
return "", errors.New("uniformMessage doesn't have the key value")
121+
}
122+
123+
config := (handler.App).GetConfig()
124+
wxKey := config.GetString("mch_api_v3_key", "")
125+
nonce := message.Resource.Nonce
126+
associatedData := message.Resource.AssociatedData
127+
cipherText := message.Resource.Ciphertext
128+
return support.DecryptAES256GCM(
129+
wxKey,
130+
associatedData,
131+
nonce,
132+
cipherText,
133+
)
134+
135+
}
136+
137+
func (handler *CustomHandler) Strict(result interface{}) {
138+
139+
bResult := true
140+
strResult := ""
141+
switch result.(type) {
142+
case bool:
143+
bResult = result.(bool)
144+
strResult = fmt.Sprintf("%t", result)
145+
case string:
146+
strResult = result.(string)
147+
if strResult != "" {
148+
bResult = false
149+
}
150+
default:
151+
return
152+
}
153+
154+
if bResult != true && handler.fail == "" {
155+
handler.Fail(strResult)
156+
}
157+
}
158+
159+
func (handler *CustomHandler) reqInfo() (content string, err error) {
160+
161+
content, err = handler.DecryptMessage()
162+
if err != nil {
163+
return "", err
164+
}
165+
166+
// save the decoded content to message resource
167+
handler.Message.Resource.Plaintext = content
168+
169+
return content, nil
170+
}

src/payment/notify/handler.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import (
55
"encoding/json"
66
"errors"
77
"fmt"
8+
"io"
9+
"net/http"
10+
811
"github.com/ArtisanCloud/PowerLibs/v3/object"
912
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/support"
1013
base2 "github.com/ArtisanCloud/PowerWeChat/v3/src/payment/base"
1114
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
1215
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
13-
"io"
14-
"net/http"
1516
)
1617

1718
type Handler struct {
@@ -24,25 +25,25 @@ type Handler struct {
2425

2526
ExternalRequest *http.Request
2627

27-
//Handle func(closure func(message *request.RequestNotify, transaction *models.Transaction, fail func(groupWelcomeTemplate string)) interface{}) *http.Response
28+
// Handle func(closure func(message *request.RequestNotify, transaction *models.Transaction, fail func(groupWelcomeTemplate string)) interface{}) *http.Response
2829
}
2930

3031
const SUCCESS = "SUCCESS"
3132
const FAIL = "FAIL"
3233

3334
func NewHandler(app kernel.ApplicationPaymentInterface, r *http.Request) *Handler {
3435

35-
//-------------- external request --------------
36-
request := &http.Request{}
36+
// -------------- external request --------------
37+
req := &http.Request{}
3738
if r != nil {
38-
request = r
39+
req = r
3940
}
4041

4142
return &Handler{
4243
App: app,
4344
Check: true,
4445
Sign: false,
45-
ExternalRequest: request,
46+
ExternalRequest: req,
4647
}
4748
}
4849

src/payment/notify/paid.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package notify
22

33
import (
4+
"net/http"
5+
46
"github.com/ArtisanCloud/PowerLibs/v3/object"
57
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
68
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
79
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
8-
"net/http"
910
)
1011

1112
type Paid struct {

src/payment/notify/refund.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package notify
22

33
import (
4+
"net/http"
5+
46
"github.com/ArtisanCloud/PowerLibs/v3/object"
57
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
68
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
79
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
8-
"net/http"
910
)
1011

1112
type Refund struct {

src/payment/notify/scanned.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package notify
22

33
import (
4+
"net/http"
5+
"reflect"
6+
47
"github.com/ArtisanCloud/PowerLibs/v3/object"
58
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/kernel"
69
"github.com/ArtisanCloud/PowerWeChat/v3/src/payment/notify/request"
7-
"net/http"
8-
"reflect"
910
)
1011

1112
type Scanned struct {

0 commit comments

Comments
 (0)