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 }