plugin alipay cpn notify over
This commit is contained in:
parent
a05a638ce8
commit
4aaef1ed12
|
@ -85,5 +85,14 @@ func (p *AlipayCpnService) Query(ctx context.Context, request *proto.QueryReques
|
|||
}
|
||||
|
||||
func (p *AlipayCpnService) Notify(_ context.Context, request *proto.NotifyRequest) (*proto.NotifyResponse, error) {
|
||||
return nil, nil
|
||||
conf, err := transConfig(request.Config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n := notifyReq(request)
|
||||
|
||||
if !Verify(n, conf.Extra.Npk) {
|
||||
return nil, fmt.Errorf("验签失败")
|
||||
}
|
||||
return notifyResp(n), nil
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestOrder(t *testing.T) {
|
|||
Order: &proto.OrderRequest_Order{
|
||||
OrderNo: "240403164049635931",
|
||||
Account: "",
|
||||
Extra: []byte(`{"phone_id":"13100720242"}`),
|
||||
Extra: []byte(`{"logon_id":"13100720242"}`),
|
||||
},
|
||||
Product: &proto.OrderRequest_Product{
|
||||
ProductNo: "3102024032977191",
|
||||
|
@ -67,9 +67,9 @@ func TestQuery(t *testing.T) {
|
|||
func TestNotify(t *testing.T) {
|
||||
in := &proto.NotifyRequest{
|
||||
Config: config,
|
||||
Queries: nil,
|
||||
Headers: []byte(`{"bizmethod":"mkt.CpnStateUpdtNotify","apptype":"00","appid":"up_49pau3fu6latj_03h","sign":"F1WQAg3CRdXsBE+1dmAy+ulNkxFWDRkI6Q\/5xcpC\/bOCbcEFeun536hfhU0In+e+5GHPbfpIqyZjjglTm60QvSwvutqOiVlEBy\/G4GpIJPuLy6hdzy9Z+f56qSa0wzIjSxKqG1VuaFd2uS4WzSrx8E6hdPotXkuKzdcRwCCq\/wlmFPVxRRIVNTf6KgqkX4aNsC\/MGdLN9E5DOfoFdC8+oPqV5N71i6SjLvrzo4yaGJm+utSqEORsWZLgfZLUw+pZGjS83rQpFEKC5UyL6KwbIefNJ7a\/5cykiNIGzTRR9Tzz+UxuoiVglJ4AeUb2vs0rL8SoUjr8aLAAqPcXzPE5wQ==","reqts":"1690252684000","version":"1.0.0","signmethod":"RSA2","reqid":"8091_lsxd6688-10","content-type":"application/json"}`),
|
||||
Body: []byte(`{"couponNum":"1","traceId":"lsxd6688-10","OperTp":"","chnlId":"9001","transChnl":"","couponNm":"众邦银行1元立减-测试","operTp":"04","couponCd":"INNER_23072510380403358473638771025186","couponId":"3102023071900090","orderAt":"0","transSeq":"lsxd6688-10","posTmn":"","discountAt":"0","couponCdInfos":[{"subAcctOperAt":"1","couponCd":"INNER_23072510380403358473638771025186"}],"mchntCd":"","transDtTm":"20230725103804"}`),
|
||||
Queries: []byte(`{"charset":"UTF-8","biz_content":"{"publish_amount":500,"activity_name":"\u90ae\u50a8\u6fc0\u6d3b\u793c47\u6ee1100-5","user_id":"2088532467083354","gmt_voucher_create":1720764021383,"voucher_status":"ENABLED","biz_type":"V_BATCH_PUBLISH","activity_id":"ACT373CCV02109242","voucher_id":"202407120007300235830O26E1ZD","order_id":"2024071200073024358301P7OES3"}","utc_timestamp":"1720764036512","sign":"oplbkc3Dcz7S8\/DSi+tBPDN593EINHQb1G0km7IgKyFfZpaYgjyyBm\/Ic2mHV6nyt9O\/eWJ0aEPLiR+rPJ3W\/ezPJCQbLascF6HshfdQa22holFnuO9xDcUH7IkR0hiQ5QxSJ+oJ6ZPU6+Po\/ercbQvwbUeQouPuZC+xWba6sznTEK7aMkv9sZJpbj3P4wD1HZKC50LEjKSAug7GZNv7B3wOqXA+Ta26l8cg2z8qHWAAdF6cYdgZ63uPKMOPDTT3gRj\/UnebE3Xjc62PYUsZJhdclJi5hW3CTTbubEmBW482rgNMIc6I+LRY8Nvspu\/8MkxU0bVsoxBEe1s0VqSLzA==","app_id":"2021004125622196","version":"1.1","sign_type":"RSA2","notify_id":"2024071200262140036056588190308607","msg_method":"alipay.user.voucher.dtbankcust.notify"}`),
|
||||
Headers: []byte(``),
|
||||
Body: []byte(``),
|
||||
}
|
||||
t.Run("TestNotify", func(t *testing.T) {
|
||||
got, err := server.Notify(context.Background(), in)
|
||||
|
@ -78,6 +78,6 @@ func TestNotify(t *testing.T) {
|
|||
return
|
||||
}
|
||||
fmt.Printf("TestNotify : %+v \n", got)
|
||||
assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
|
||||
//assert.Equal(t, int(proto.Status_SUCCESS), int(got.Result.Status))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,25 +1,23 @@
|
|||
package po
|
||||
|
||||
type Voucher struct {
|
||||
ActivityID string `json:"activity_id"`
|
||||
ActivityName string `json:"activity_name"`
|
||||
VoucherID string `json:"voucher_id"`
|
||||
UserID string `json:"user_id"`
|
||||
UseTime string `json:"use_time"`
|
||||
UseAmount string `json:"use_amount"`
|
||||
BizType string `json:"biz_type"`
|
||||
RefundTime string `json:"refund_time"`
|
||||
RefundAmount string `json:"refund_amount"`
|
||||
VoucherStatus string `json:"voucher_status"`
|
||||
OrderID string `json:"order_id"`
|
||||
TradeNo string `json:"trade_no"`
|
||||
GmtVoucherCreate string `json:"gmt_voucher_create"`
|
||||
import "plugins/alipay_cpn/internal/vo"
|
||||
|
||||
type NotifyBizContent struct {
|
||||
PublishAmount int64 `json:"publish_amount"`
|
||||
ActivityName string `json:"activity_name"`
|
||||
UserID string `json:"user_id"`
|
||||
GmtVoucherCreate int64 `json:"gmt_voucher_create"`
|
||||
VoucherStatus vo.VoucherStatus `json:"voucher_status"`
|
||||
BizType vo.NotifyBizType `json:"biz_type"`
|
||||
ActivityID string `json:"activity_id"`
|
||||
VoucherID string `json:"voucher_id"`
|
||||
OrderID string `json:"order_id"`
|
||||
}
|
||||
|
||||
type Notify struct {
|
||||
AppId string `json:"app_id"`
|
||||
Charset string `json:"charset"`
|
||||
UtcTimestamp string `json:"utc_timestamp"`
|
||||
AppId string `json:"app_id"`
|
||||
Version string `json:"version"`
|
||||
SignType string `json:"sign_type"`
|
||||
NotifyId string `json:"notify_id"`
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"codeup.aliyun.com/6552e56cc3b2728a4557fc18/plugin/proto"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html"
|
||||
"plugins/alipay_cpn/internal/po"
|
||||
"plugins/alipay_cpn/internal/vo"
|
||||
"time"
|
||||
|
@ -120,9 +121,21 @@ func queryResp(request *proto.QueryRequest, resp po.QueryResp) *proto.QueryRespo
|
|||
}
|
||||
|
||||
func notifyReq(in *proto.NotifyRequest) *po.Notify {
|
||||
return nil
|
||||
var n *po.Notify
|
||||
_ = json.Unmarshal(in.Queries, &n)
|
||||
n.BizContent = html.UnescapeString(n.BizContent)
|
||||
return n
|
||||
}
|
||||
|
||||
func notifyResp(request *proto.NotifyRequest, n *po.Notify) *proto.NotifyResponse {
|
||||
return nil
|
||||
func notifyResp(n *po.Notify) *proto.NotifyResponse {
|
||||
var b po.NotifyBizContent
|
||||
_ = json.Unmarshal([]byte(n.BizContent), &b)
|
||||
return &proto.NotifyResponse{
|
||||
Result: &proto.Result{
|
||||
Status: b.BizType.GetOrderStatus(),
|
||||
OrderNo: b.OrderID,
|
||||
TradeNo: b.VoucherID,
|
||||
Message: fmt.Sprintf("%s, %s", b.BizType.GetText(), b.VoucherStatus.GetText()),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,26 @@ func Sign(data string, privateKeyPEM []byte) (string, error) {
|
|||
return base64.StdEncoding.EncodeToString(signature), nil
|
||||
}
|
||||
|
||||
func Verify(data, signature string, publicKeyPEM []byte) bool {
|
||||
func Verify(n *po.Notify, publicKeyPEM string) bool {
|
||||
var strToBeSigned strings.Builder
|
||||
uv := url.Values{}
|
||||
kvRows := utils.SortStructJsonTag(n)
|
||||
for _, kv := range kvRows {
|
||||
if kv.Key == "sign" {
|
||||
continue
|
||||
}
|
||||
if kv.Key == "sign_type" {
|
||||
continue
|
||||
}
|
||||
uv.Set(kv.Key, kv.Value)
|
||||
strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
|
||||
}
|
||||
s := strings.TrimRight(strToBeSigned.String(), "&")
|
||||
fmt.Println(s)
|
||||
return check(s, n.Sign, []byte(utils.NewPublic().Build(publicKeyPEM)))
|
||||
}
|
||||
|
||||
func check(data, signature string, publicKeyPEM []byte) bool {
|
||||
block, _ := pem.Decode(publicKeyPEM)
|
||||
if block == nil {
|
||||
fmt.Println("failed to parse PEM block containing the public key")
|
||||
|
|
|
@ -5,18 +5,27 @@ import "codeup.aliyun.com/6552e56cc3b2728a4557fc18/plugin/proto"
|
|||
type NotifyBizType string
|
||||
|
||||
const (
|
||||
NotifyBizTypeUse NotifyBizType = "V_USE"
|
||||
NotifyBizTypeRefund NotifyBizType = "V_REFUND"
|
||||
NotifyBizTypeBatchPublish NotifyBizType = "V_BATCH_PUBLISH"
|
||||
NotifyBizTypeExpire NotifyBizType = "V_EXPIRE"
|
||||
NotifyBizTypeDelete NotifyBizType = "V_DELETE"
|
||||
NotifyBizTypeUse NotifyBizType = "V_USE"
|
||||
NotifyBizTypeRefund NotifyBizType = "V_REFUND"
|
||||
)
|
||||
|
||||
var notifyBizTypeTextMap = map[NotifyBizType]string{
|
||||
NotifyBizTypeUse: "券核销",
|
||||
NotifyBizTypeRefund: "券退款",
|
||||
NotifyBizTypeUse: "券核销",
|
||||
NotifyBizTypeRefund: "券退款",
|
||||
NotifyBizTypeBatchPublish: "券发放",
|
||||
NotifyBizTypeExpire: "券过期",
|
||||
NotifyBizTypeDelete: "券删除",
|
||||
}
|
||||
|
||||
var notifyBizTypeMap = map[NotifyBizType]proto.Status{
|
||||
NotifyBizTypeUse: proto.Status_WRITE_OFF,
|
||||
NotifyBizTypeRefund: proto.Status_REFUND,
|
||||
NotifyBizTypeBatchPublish: proto.Status_SUCCESS,
|
||||
NotifyBizTypeDelete: proto.Status_DELETE,
|
||||
NotifyBizTypeExpire: proto.Status_OVERDUE,
|
||||
NotifyBizTypeUse: proto.Status_WRITE_OFF,
|
||||
NotifyBizTypeRefund: proto.Status_REFUND,
|
||||
}
|
||||
|
||||
func (o NotifyBizType) GetText() string {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package vo
|
||||
|
||||
type VoucherStatus string
|
||||
|
||||
const (
|
||||
VoucherStatusEnabled VoucherStatus = "ENABLED"
|
||||
VoucherStatusDisabled VoucherStatus = "DISABLED"
|
||||
)
|
||||
|
||||
var voucherStatusTextMap = map[VoucherStatus]string{
|
||||
VoucherStatusEnabled: "券状态:可用",
|
||||
VoucherStatusDisabled: "券状态:不可用",
|
||||
}
|
||||
|
||||
func (o VoucherStatus) GetText() string {
|
||||
msg, ok := voucherStatusTextMap[o]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return msg
|
||||
}
|
Loading…
Reference in New Issue