init: 1.0.0
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
package alipay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/url"
|
||||
|
||||
"github.com/perfect-panel/ppanel-server/pkg/logger"
|
||||
"github.com/perfect-panel/ppanel-server/pkg/tool"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
AppId string
|
||||
PrivateKey string
|
||||
PublicKey string
|
||||
InvoiceName string
|
||||
NotifyURL string
|
||||
Sandbox bool
|
||||
}
|
||||
|
||||
type Notification struct {
|
||||
OrderNo string
|
||||
Amount int64
|
||||
Status Status
|
||||
}
|
||||
|
||||
type Status string
|
||||
|
||||
const (
|
||||
Success Status = "TRADE_SUCCESS"
|
||||
Pending Status = "WAIT_BUYER_PAY"
|
||||
Closed Status = "TRADE_CLOSED"
|
||||
Finished Status = "TRADE_FINISHED"
|
||||
Error Status = "TRADE_ERROR"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
Config
|
||||
client *alipay.Client
|
||||
}
|
||||
type Order struct {
|
||||
OrderNo string
|
||||
Amount int64
|
||||
}
|
||||
|
||||
func NewClient(c Config) *Client {
|
||||
client, err := alipay.New(c.AppId, c.PrivateKey, c.Sandbox)
|
||||
if err != nil {
|
||||
logger.Error("[Alipay] NewClient failed: ", logger.Field("errors", err), logger.Field("config", c))
|
||||
return nil
|
||||
}
|
||||
err = client.LoadAliPayPublicKey(c.PublicKey)
|
||||
if err != nil {
|
||||
logger.Error("[Alipay] NewClient failed: ", logger.Field("errors", err), logger.Field("config", c))
|
||||
}
|
||||
return &Client{
|
||||
Config: c,
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) PreCreateTrade(ctx context.Context, order Order) (string, error) {
|
||||
amountString := tool.FormatFloat(float64(order.Amount)/float64(100), 2)
|
||||
trade, err := c.client.TradePreCreate(ctx, alipay.TradePreCreate{
|
||||
Trade: alipay.Trade{
|
||||
OutTradeNo: order.OrderNo,
|
||||
TotalAmount: amountString,
|
||||
Subject: c.InvoiceName,
|
||||
NotifyURL: c.NotifyURL,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if trade.Code != alipay.CodeSuccess {
|
||||
return "", errors.New("PreCreateTrade failed: " + trade.Msg)
|
||||
}
|
||||
return trade.QRCode, nil
|
||||
}
|
||||
|
||||
func (c *Client) QueryTrade(ctx context.Context, orderNo string) (Status, error) {
|
||||
trade, err := c.client.TradeQuery(ctx, alipay.TradeQuery{
|
||||
OutTradeNo: orderNo,
|
||||
})
|
||||
if err != nil {
|
||||
return Error, err
|
||||
}
|
||||
switch trade.TradeStatus {
|
||||
case alipay.TradeStatusSuccess:
|
||||
return Success, nil
|
||||
case alipay.TradeStatusWaitBuyerPay:
|
||||
return Pending, nil
|
||||
case alipay.TradeStatusClosed:
|
||||
return Closed, nil
|
||||
case alipay.TradeStatusFinished:
|
||||
return Finished, nil
|
||||
default:
|
||||
return Error, errors.New("QueryTrade failed: " + trade.Msg)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) DecodeNotification(form url.Values) (*Notification, error) {
|
||||
notify, err := c.client.DecodeNotification(form)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Notification{
|
||||
OrderNo: notify.OutTradeNo,
|
||||
Amount: int64(tool.FormatStringToFloat(notify.TotalAmount) * 100),
|
||||
Status: Status(notify.TradeStatus),
|
||||
}, nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package alipay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestClientPreCreateTrade(t *testing.T) {
|
||||
t.Skipf("Skip TestClientPreCreateTrade")
|
||||
cfg := Config{
|
||||
InvoiceName: "XrayR",
|
||||
NotifyURL: "https://example.com/alipay/notify",
|
||||
Sandbox: true,
|
||||
}
|
||||
c := NewClient(cfg)
|
||||
order := Order{
|
||||
OrderNo: "20210701000001",
|
||||
Amount: 100,
|
||||
}
|
||||
qr, err := c.PreCreateTrade(context.Background(), order)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(qr)
|
||||
}
|
||||
Reference in New Issue
Block a user