light-pkg/myPay/alipay.go

146 lines
3.6 KiB
Go
Raw Normal View History

2024-12-18 03:41:30 +08:00
package myPay
import (
"context"
"errors"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"github.com/shopspring/decimal"
"net/http"
)
type AliPay struct {
ctx context.Context
cli *alipay.Client
params *AliPayImpl
orderNo string
amount int
description string
notifyUrl string
returnUrl string
}
func NewAliPay(params *AliPayImpl) *AliPay {
client, err := alipay.NewClient(params.AppId, params.PrivateKey, params.IsProd)
if err != nil {
panic(err.Error())
}
// 打开Debug开关输出日志默认是关闭的
if params.IsProd {
client.DebugSwitch = gopay.DebugOff
} else {
client.DebugSwitch = gopay.DebugOn
}
client.SetLocation(alipay.LocationShanghai).
SetCharset(alipay.UTF8).
SetSignType(alipay.RSA2).
AutoVerifySign([]byte(params.PublicKey))
if err := client.SetCertSnByContent([]byte(params.AppCertContent), []byte(params.AliPayRootCertContent), []byte(params.PublicKey)); err != nil {
panic(err.Error())
}
return &AliPay{params: params, cli: client, ctx: context.Background()}
}
func (t *AliPay) GetCli() *alipay.Client {
return t.cli
}
func (t *AliPay) SetCommonConfig(notifyUrl string, returnUrl string) *AliPay {
t.notifyUrl = notifyUrl
t.returnUrl = returnUrl
return t
}
func (t *AliPay) SetOrderInfo(orderNo string, amount int, description string) *AliPay {
t.orderNo = orderNo
t.amount = amount
t.description = description
return t
}
func (t *AliPay) SetCertSnByContent(appCertContent, aliPayRootCertContent []byte) error {
return t.cli.SetCertSnByContent(appCertContent, aliPayRootCertContent, []byte(t.params.PublicKey))
}
func (t *AliPay) SetCertSnByPath(appCertPath, aliPayRootCertPath, aliPayPublicCertPath string) error {
return t.cli.SetCertSnByPath(appCertPath, aliPayRootCertPath, aliPayPublicCertPath)
}
func (t *AliPay) setBodyMap() gopay.BodyMap {
if t.description == "" || t.orderNo == "" || t.notifyUrl == "" {
panic("param is empty")
}
if t.amount == 0 {
panic("amount is zero")
}
// 配置公共参数
t.cli.SetNotifyUrl(t.notifyUrl).
SetReturnUrl(t.returnUrl)
bm := make(gopay.BodyMap)
bm.Set("subject", t.description)
bm.Set("out_trade_no", t.orderNo)
bm.Set("total_amount", t.fen2Yuan(uint64(t.amount)))
return bm
}
func (t *AliPay) GetWapPay(quitUrl string) (string, error) {
bm := t.setBodyMap()
bm.Set("quit_url", quitUrl)
bm.Set("product_code", "QUICK_WAP_WAY")
return t.cli.TradeWapPay(t.ctx, bm)
}
func (t *AliPay) GetPagePay() (string, error) {
bm := t.setBodyMap()
bm.Set("product_code", "FAST_INSTANT_TRADE_PAY")
return t.cli.TradePagePay(t.ctx, bm)
}
func (t *AliPay) GetAppPay() (string, error) {
bm := t.setBodyMap()
bm.Set("product_code", "QUICK_MSECURITY_PAY")
return t.cli.TradeAppPay(t.ctx, bm)
}
func (t *AliPay) Notify(req *http.Request) (*AlipayNotifyResp, error) {
notifyReq, err := alipay.ParseNotifyToBodyMap(req)
if err != nil {
return nil, errors.New("解析回调失败")
}
if ok, err := alipay.VerifySign(t.params.PublicKey, notifyReq); err != nil || ok == false {
return nil, errors.New("sign Error")
}
return &AlipayNotifyResp{resp: notifyReq}, nil
}
func (t *AliPay) GetOrderNo() string {
return t.orderNo
}
func (t *AliPay) GetAmount() int {
return t.amount
}
type AliPayImpl struct {
AppId string
PublicKey string
PrivateKey string
IsProd bool
AppCertContent string
AliPayRootCertContent string
}
func (t *AliPay) fen2Yuan(price uint64) string {
d := decimal.New(1, 2)
result := decimal.NewFromInt(int64(price)).DivRound(d, 2).String()
return result
}