印度包网
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
2.9 KiB

1 year ago
package base
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
"reflect"
"server/modules/pay/values"
"server/pb"
"strings"
"github.com/gin-gonic/gin"
"github.com/gogo/protobuf/proto"
"github.com/liangdas/mqant/log"
)
type HttpType int
const (
HttpTypeInvalid = iota
HttpTypeJson
HttpTypeForm
HttpTypeAll
)
type Base struct {
Channel values.PayWay
PayReq *pb.InnerRechargeReq
WithdrawReq *pb.InnerWithdrawReq
SignKey string
ShouldSignUpper bool
HttpType HttpType
ReqURL string
Opt int // 1支付 2退出
Status int // 返回的状态
Resp interface{}
CallbackReq interface{}
CallbackResp CallbackResp
SignPassStr []string // 不参与签名的字段
WhiteIPs []string // ip白名单
Sub
C *gin.Context
}
type CallbackResp struct {
Msg string
OrderID string
APIOrderID string
FailMessage string
Success bool
}
type Sub interface {
PackHeader(header http.Header) // 生成请求头
PackReq() interface{} // 生成支付请求体
GetResp() (proto.Message, error) // 获取返回
CheckSign(str string) bool // 验签同时给callbackresp赋值
}
func NewRechargeBase(req *pb.InnerRechargeReq) *Base {
values.PackPay(req)
base := &Base{
Channel: values.PayWay(req.Channel),
PayReq: req,
Opt: 1,
}
return base
}
func NewWithdrawBase(req *pb.InnerWithdrawReq) *Base {
values.PackWithdraw(req)
base := &Base{
Channel: values.PayWay(req.Channel),
WithdrawReq: req,
Opt: 2,
}
return base
}
func NewCallbackBase(opt int) *Base {
base := &Base{
Opt: opt,
}
return base
}
func (b *Base) PackHeader(header http.Header) {
switch b.HttpType {
case HttpTypeJson:
header.Set("Content-Type", "application/json")
case HttpTypeForm:
header.Set("Content-Type", "application/x-www-form-urlencoded")
}
b.Sub.PackHeader(header)
}
func (b *Base) Req() ([]byte, error) {
send := b.Sub.PackReq()
reqData := b.PackReq(send)
log.Debug("Req to:%v,req:%v", b.ReqURL, reqData)
req, err := http.NewRequest("POST", b.ReqURL, strings.NewReader(reqData))
if err != nil {
log.Error("err:%v", err)
return nil, errors.New("pay fail")
}
b.PackHeader(req.Header)
b.Status = values.Post(req, b.Resp)
ret, err := b.Sub.GetResp()
if err != nil {
log.Error("err:%v", err)
return nil, err
}
data, _ := proto.Marshal(ret)
return data, nil
}
func (b *Base) PackReq(send interface{}) string {
ref := reflect.ValueOf(send)
reft := reflect.TypeOf(send)
if ref.Kind() == reflect.Ptr {
ref = ref.Elem()
reft = reft.Elem()
}
switch b.HttpType {
case HttpTypeJson:
reqData, _ := json.Marshal(send)
return string(reqData)
case HttpTypeForm:
data := url.Values{}
for i := 0; i < ref.NumField(); i++ {
if ref.Field(i).IsZero() {
continue
}
data.Set(reft.Field(i).Tag.Get("json"), fmt.Sprintf("%v", ref.Field(i).Interface()))
}
return data.Encode()
}
return ""
}