Files
openbilibili/app/service/main/ugcpay/service/pay/pay.go
2019-04-22 20:46:32 +08:00

183 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package pay
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"net/url"
"strconv"
"time"
"go-common/library/log"
"github.com/pkg/errors"
)
// Pay is.
type Pay struct {
ID string
Token string
OrderTTL int
NotifyURL string
RefundNotifyURL string
}
// Create 返回订单创建param
func (p *Pay) Create(orderID string, productID int64, price int64, deviceType int64, serviceType int, mid int64, title string) (params url.Values) {
params = make(url.Values)
params.Set("customerId", p.ID)
params.Set("serviceType", strconv.Itoa(serviceType))
params.Set("orderId", orderID)
params.Set("orderCreateTime", strconv.FormatInt(time.Now().Unix()*1000, 10))
params.Set("orderExpire", strconv.Itoa(p.OrderTTL))
params.Set("payAmount", strconv.FormatInt(price, 10))
params.Set("originalAmount", strconv.FormatInt(price, 10))
params.Set("deviceType", strconv.FormatInt(deviceType, 10))
params.Set("notifyUrl", p.NotifyURL)
params.Set("productId", strconv.FormatInt(productID, 10))
params.Set("showTitle", title)
params.Set("traceId", p.TraceID())
params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10))
params.Set("version", "1.0")
params.Set("uid", strconv.FormatInt(mid, 10))
return
}
// Query 返回订单查询param
func (p *Pay) Query(orderID string) (params url.Values) {
params = make(url.Values)
params.Set("customerId", p.ID)
params.Set("orderIds", orderID)
params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10))
params.Set("traceId", p.TraceID())
params.Set("version", "1.0")
return
}
// TraceID 生成traceID
func (p *Pay) TraceID() string {
return strconv.FormatInt(time.Now().UnixNano(), 10)
}
// Refund 原路返回退款params
func (p *Pay) Refund(txID string, refundFee int64, refundDesc string) (params url.Values) {
params = make(url.Values)
params.Set("customerId", p.ID)
params.Set("txId", txID)
params.Set("totalAmount", strconv.FormatInt(refundFee, 10))
params.Set("refundAmount", strconv.FormatInt(refundFee, 10))
params.Set("refundDesc", refundDesc)
params.Set("notifyUrl", p.RefundNotifyURL)
params.Set("version", "1.0")
params.Set("traceId", p.TraceID())
params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10))
return
}
// Cancel 返回订单取消param
func (p *Pay) Cancel(orderID string) (params url.Values) {
params = make(url.Values)
params.Set("customerId", p.ID)
params.Set("orderId", orderID)
params.Set("timestamp", strconv.FormatInt(time.Now().Unix()*1000, 10))
params.Set("traceId", p.TraceID())
params.Set("version", "1.0")
return
}
// ToJSON 将param转换为支付平台请求的body:JSON数据
func (p *Pay) ToJSON(params url.Values) (j string, err error) {
var (
payBytes []byte
pmap = make(map[string]string)
)
for k, v := range params {
if len(v) > 0 {
pmap[k] = v[0]
}
}
if payBytes, err = json.Marshal(pmap); err != nil {
err = errors.Wrapf(err, "pay.ToJSON : %s", params.Encode())
return
}
j = string(payBytes)
return
}
// DeviceType 通过platform获得支付平台DeviceType
func (p *Pay) DeviceType(platform string) (t int64) {
// 支付设备渠道类型, 1 pc 2 webapp 3 app 4jsapi 5 server 6小程序支付 7聚合二维码支付
switch platform {
case "ios", "android":
return 3
default:
return 1
}
}
// ServiceType 通过platform获得支付平台ServiceType
func (p *Pay) ServiceType(platform string) (t int) {
/*
业务方业务类型用于业务方定制支付渠道不同的serviceType可以配置成不同的支付渠道列表
每个渠道列表可以自定义顺序,以下值具有特殊含义:
1. 7 签约代扣类,如微信代扣,支付宝代扣 5.25 支持)
2. 100 表示IAP支付 5.24 支持)
3. 100 IAP代扣也传100根据subscribeType区分是不是代扣
4. 99 表示 客户端B币快捷支付 5.26 支持)
5 98 表示 业务方B币快捷支付1.1 B币支付
*/
switch platform {
case "ios", "android":
return 0
default:
return 99
}
}
// Sign 对param进行签名
func (p *Pay) Sign(params url.Values) (err error) {
params.Set("signType", "MD5")
sortedStr := params.Encode()
if sortedStr, err = url.QueryUnescape(sortedStr); err != nil {
return
}
b := bytes.Buffer{}
b.WriteString(sortedStr)
b.WriteString("&token=" + p.Token)
signMD5 := md5.Sum(b.Bytes())
sign := hex.EncodeToString(signMD5[:])
params.Set("sign", sign)
return
}
// Verify 对param进行签名验证
func (p *Pay) Verify(params url.Values) (ok bool) {
var (
rs = params.Get("sign")
s string
)
ok = false
defer func() {
if !ok {
params.Set("sign", rs)
log.Error("Verify pay sign error, expect : %s, actual : %s, params : %s", s, rs, params.Encode())
}
}()
if rs == "" {
return
}
params.Del("sign")
if err := p.Sign(params); err != nil {
log.Error("Verify pay sign error : %+v", err)
return
}
s = params.Get("sign")
if rs == s {
ok = true
return
}
return
}