159 lines
4.8 KiB
Go
159 lines
4.8 KiB
Go
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
|
|
}
|