package biz import ( "context" "encoding/json" "fmt" "sandc/pkg/middleware/xhttp" "sandc/pkg/utils" "sandc/pkg/xcrypto/pscrypto" "github.com/go-kratos/kratos/v2/log" ) // PayoutReq 支付请求参数 type PayoutReq struct { Name string `json:"name,omitempty"` Phone string `json:"phone,omitempty"` Email string `json:"email,omitempty"` Account string `json:"account,omitempty"` AccountType string `json:"account_type,omitempty"` Method string `json:"method,omitempty"` Channel string `json:"channel,omitempty"` CustomCode string `json:"custom_code,omitempty"` FeeBear string `json:"fee_bear,omitempty"` Amount string `json:"amount,omitempty"` SourceCurrency string `json:"source_currency,omitempty"` ArrivalCurrency string `json:"arrival_currency,omitempty"` NotifyUrl string `json:"notify_url,omitempty"` AdditionalRemark string `json:"additional_remark,omitempty"` Country string `json:"country,omitempty"` Document_id string `json:"document_id,omitempty"` Document_type string `json:"document_type,omitempty"` ClientData string `json:"clientData,omitempty"` } // PayoutReply 支付请求响应 type PayoutReply struct { Code int `json:"code,omitempty"` Msg string `json:"msg,omitempty"` Time int `json:"time,omitempty"` Data PayoutReplyData `json:"data,omitempty"` } type PayoutReplyData struct { Id string `json:"id,omitempty"` CustomCode string `json:"custom_code,omitempty"` ArrivalAmount string `json:"arrival_amount,omitempty"` ArrivalCurrency string `json:"arrival_currency,omitempty"` SourceAmount string `json:"source_amount,omitempty"` SourceCurrency string `json:"source_currency,omitempty"` Status string `json:"status,omitempty"` } type PagsmileClient struct { log *log.Helper out *PayoutClient } type PayoutClient struct { AppId string AppKey string ApiUrl string NotifyUrl string } func NewPagsmileClient(out *PayoutClient, logger log.Logger) *PagsmileClient { return &PagsmileClient{ out: out, log: log.NewHelper(logger), } } // genAuthorization 生成签名授权 func (uc *PayoutClient) genAuthorization(ctx context.Context, req interface{}) string { mapJson := utils.StructToMapJson(req) sign := pscrypto.GetSign(mapJson, uc.AppKey) return sign } // Payout 打款 func (c *PayoutClient) Payout(ctx context.Context, req *PayoutReq) (*PayoutReplyData, error) { req.NotifyUrl = c.NotifyUrl auth := c.genAuthorization(ctx, *req) str := fmt.Sprintf("auth: %s", auth) fmt.Println(str) log.Info(str) b, err := json.Marshal(req) if err != nil { return nil, fmt.Errorf("Payout marshl json failed: %w", err) } // 记录当前payout请求全数据: str = fmt.Sprintf("payout req: %s - %s\n", req.CustomCode, string(b)) fmt.Println(str) log.Info(str) // bhttp, err := bhttp.NewBhttpClient() // if err != nil { // return nil, fmt.Errorf("Payout new bhttp client failed: %w", err) // } // bhttp.SetHeader("Authorization", auth) // bhttp.SetHeader("AppId", c.AppId) // bhttp.SetBody(b) // payoutUrl := fmt.Sprintf("%s/api/payout", c.ApiUrl) // str = fmt.Sprintf("payoutUrl:%s", payoutUrl) // fmt.Println(str) // log.Info(str) // body, err := bhttp.DoPost(payoutUrl) // if err != nil { // return nil, fmt.Errorf("Payout do post failed: %w", err) // } // str = fmt.Sprintf("[%s] payout body: %s - %s\n", time.Now().Format("2006-01-02 15:04:05"), req.CustomCode, string(body)) // fmt.Println(str) // log.Info(str) var reply PayoutReply // err = json.Unmarshal(body, &reply) // if err != nil { // return nil, fmt.Errorf("Payout unmarshal failed: %w", err) // } // // if reply.Code != http.StatusOK { // return nil, fmt.Errorf("Payout error: %s", reply.Msg) // } // // if reply.Data.Status != "IN_PROCESSING" { // return nil, fmt.Errorf("Payout failed: %s", reply.Data.Status) // } reply.Data.Id = "Test" reply.Data.CustomCode = req.CustomCode return &reply.Data, nil } // PayoutNotifyReq 打款回调请求参数 type PayoutNotifyReq struct { PayoutId string `json:"payoutId,omitempty"` CustomCode string `json:"custom_code,omitempty"` Status string `json:"status,omitempty"` Msg string `json:"msg,omitempty"` Timestamp int64 `json:"timestamp,omitempty"` } // PayoutNotify 打款回调 func (c *PayoutClient) PayoutNotify(ctx context.Context, req *PayoutNotifyReq) error { // 验证回调签名 auth := c.genAuthorization(ctx, *req) fmt.Println("auth: ", auth) httpContext := xhttp.RequestFromContext(ctx) if httpContext == nil { return fmt.Errorf("PayoutNotify http context is nil") } authHeader := httpContext.Header().Get("Authorization") if authHeader != auth { fmt.Printf("authHeader: %s, auth: %s \n", authHeader, auth) return fmt.Errorf("PayoutNotify auth failed") } return nil }