service/library/payclients/alipaycli/client.go

176 lines
5.1 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 alipaycli
import (
"context"
"fmt"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"net/http"
"service/bizcommon/util"
"service/library/configcenter"
"service/library/logger"
"time"
)
const (
DefaultOrderTimeoutSeconds = 900 // 默认订单超时时间,单位: s
)
var defaultAlipayClient *AlipayClient
func GetDefaultAlipayClient() *AlipayClient {
return defaultAlipayClient
}
type AlipayClient struct {
*alipay.Client
}
func Init(cfg *configcenter.AlipayClientConfig) (err error) {
alipayCli, err := alipay.NewClient(cfg.Appid, cfg.PrivateKey, true)
if err != nil {
logger.Error("NewClient fail, cfg: %v, err: %v", util.ToJson(cfg), err)
return
}
alipayCli.SetNotifyUrl(cfg.NotifyUrl)
err = alipayCli.SetCertSnByPath(
"/app/wishpal-ironfan/etc/mix/alipaycert/appCertPublicKey_2021004115647165.crt",
"/app/wishpal-ironfan/etc/mix/alipaycert/alipayRootCert.crt",
"/app/wishpal-ironfan/etc/mix/alipaycert/alipayCertPublicKey_RSA2.crt",
)
if err != nil {
logger.Error("SetCertSnByPath fail, cfg: %v, err: %v", util.ToJson(cfg), err)
return
}
defaultAlipayClient = &AlipayClient{
Client: alipayCli,
}
return
}
// 解析回调参数
func (c *AlipayClient) ParseNotify(req *http.Request) (notify gopay.BodyMap, err error) {
// 解析参数
notifyTmp, err := alipay.ParseNotifyToBodyMap(req)
if err != nil {
logger.Error("ParseNotifyToBodyMap fail, req: %v, err: %v", util.ToJson(req), err)
return
}
logger.Info("Alipay ParseNotify, %v", util.ToJson(notifyTmp))
// 验签
ok, err := alipay.VerifySignWithCert("/app/wishpal-ironfan/etc/mix/alipaycert/alipayCertPublicKey_RSA2.crt", notifyTmp)
if !ok {
logger.Error("VerifySign fail, not ok, bm: %v", util.ToJson(notifyTmp))
return
}
notify = notifyTmp
return
}
// 支付宝 app支付
type AppPayParam struct {
OutTradeNo string // 商家订单id我们自己的订单id
Subject string // 主题
TotalAmount int64 // 金额,单位:分
TimeOutSeconds int // 订单有效时间,单位:秒
}
func (c *AlipayClient) AppPay(ctx context.Context, param *AppPayParam) (alipayAppParamStr string, err error) {
if param.TimeOutSeconds <= 0 {
param.TimeOutSeconds = DefaultOrderTimeoutSeconds
}
bm := gopay.BodyMap{
"out_trade_no": param.OutTradeNo,
"subject": param.Subject,
"total_amount": fmt.Sprintf("%.2f", float64(param.TotalAmount)/100.0),
"time_expire": time.Now().Add(time.Second * time.Duration(param.TimeOutSeconds)).Format("2006-01-02 15:04:05"),
"notify_url": c.NotifyUrl,
}
alipayAppParamStr, err = c.TradeAppPay(ctx, bm)
if err != nil {
return
}
logger.Info("alipay TradeAppPay param: %v", alipayAppParamStr)
return
}
// 支付宝 手机web支付
type WapPayParam struct {
OutTradeNo string // 商家订单id我们自己的订单id
Subject string // 主题
TotalAmount int64 // 金额,单位:分
TimeOutSeconds int // 订单有效时间,单位:秒
ReturnUrl string // 支付宝return_url
}
func (c *AlipayClient) WapPay(ctx context.Context, param *WapPayParam) (alipayWapParamStr string, err error) {
if param.TimeOutSeconds <= 0 {
param.TimeOutSeconds = DefaultOrderTimeoutSeconds
}
bm := gopay.BodyMap{
"out_trade_no": param.OutTradeNo,
"subject": param.Subject,
"total_amount": fmt.Sprintf("%.2f", float64(param.TotalAmount)/100.0),
"time_expire": time.Now().Add(time.Second * time.Duration(param.TimeOutSeconds)).Format("2006-01-02 15:04:05"),
"notify_url": c.NotifyUrl,
}
if len(param.ReturnUrl) > 0 {
bm["return_url"] = param.ReturnUrl
}
alipayWapParamStr, err = c.TradeWapPay(ctx, bm)
if err != nil {
return
}
logger.Info("alipay TradeWapPay param: %v", alipayWapParamStr)
return
}
// 支付宝单笔转账
type UniTransferParam struct {
OutBizNo string // 商家订单id我们自己的订单id
Amount int64 // 金额,单位:分
Title string // 转账业务的标题,用于在支付宝用户的账单里显示。
AlipayLoginId string // 支付宝登录账号
AlipayName string // 支付宝真实姓名
}
func (c *AlipayClient) UniTransfer(ctx context.Context, param *UniTransferParam) (resp *alipay.FundTransUniTransferResponse, err error) {
bm := gopay.BodyMap{
"out_biz_no": param.OutBizNo,
"trans_amount": fmt.Sprintf("%.2f", float64(param.Amount)/100.0),
"biz_scene": "DIRECT_TRANSFER",
"product_code": "TRANS_ACCOUNT_NO_PWD",
"order_title": param.Title,
"payee_info": map[string]interface{}{
"identity": param.AlipayLoginId,
"identity_type": "ALIPAY_LOGON_ID",
"name": param.AlipayName,
},
}
resp, err = c.FundTransUniTransfer(ctx, bm)
if err != nil {
return
}
logger.Info("alipay UniTransfer param: %v, resp: %v", bm.JsonBody(), util.ToJson(resp))
return
}
// 订单查询
type QueryOrderParam struct {
OutTradeNo string // 商家订单id我们自己的订单id
}
func (c *AlipayClient) QueryOrder(ctx context.Context, param *QueryOrderParam) (resp *alipay.TradeQueryResponse, err error) {
bm := gopay.BodyMap{
"out_trade_no": param.OutTradeNo,
}
resp, err = c.TradeQuery(ctx, bm)
if err != nil {
return
}
return
}