85 lines
3.0 KiB
Go
85 lines
3.0 KiB
Go
// Package payments manages WeChat Native recharge orders for organization wallets.
|
|
package payments
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
ErrNotFound = errors.New("payment order not found")
|
|
ErrConflict = errors.New("payment order conflicts with existing data")
|
|
ErrInvalidAmount = errors.New("invalid payment amount")
|
|
ErrUnavailable = errors.New("payment unavailable")
|
|
ErrVerification = errors.New("payment verification failed")
|
|
ErrRemoteNotFound = errors.New("remote payment order not found")
|
|
)
|
|
|
|
const (
|
|
StatusPending = "pending"
|
|
StatusPaid = "paid"
|
|
StatusClosed = "closed"
|
|
)
|
|
|
|
type Order struct {
|
|
ID string `json:"id"`
|
|
OrganizationID string `json:"organizationId"`
|
|
AccountID string `json:"accountId"`
|
|
RequestKey string `json:"-"`
|
|
MchID string `json:"-"`
|
|
AppID string `json:"-"`
|
|
AmountFen int64 `json:"amountFen"`
|
|
Currency string `json:"currency"`
|
|
Status string `json:"status"`
|
|
CodeURL string `json:"codeUrl,omitempty"`
|
|
TransactionID string `json:"transactionId,omitempty"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
ExpiresAt time.Time `json:"expiresAt"`
|
|
PaidAt *time.Time `json:"paidAt,omitempty"`
|
|
}
|
|
|
|
type Transaction struct {
|
|
OrderID, MchID, AppID, TransactionID, TradeState, Currency string
|
|
AmountFen int64
|
|
SuccessTime time.Time
|
|
}
|
|
|
|
// Repository settlement must validate the stored order identity and amount,
|
|
// atomically post the wallet ledger and mark paid, and reject reused transaction IDs.
|
|
type Repository interface {
|
|
CreatePaymentOrder(context.Context, Order) (Order, error)
|
|
GetPaymentOrder(context.Context, string) (Order, error)
|
|
ListPaymentOrders(context.Context, string, int) ([]Order, error)
|
|
PendingPaymentOrders(context.Context, int) ([]Order, error)
|
|
UpdatePaymentOrder(context.Context, string, string, string) (Order, error)
|
|
SettlePaymentOrder(context.Context, Transaction) (Order, error)
|
|
}
|
|
|
|
type Provider interface {
|
|
Create(context.Context, Order) (string, error)
|
|
Query(context.Context, string) (Transaction, error)
|
|
Close(context.Context, string) error
|
|
ParseNotification(context.Context, *http.Request) (Transaction, error)
|
|
}
|
|
|
|
type Config struct {
|
|
Enabled bool
|
|
MchID, AppID, NotifyURL string
|
|
MerchantSerial, PrivateKeyPEM, APIv3Key string
|
|
WechatPublicKeyID, WechatPublicKeyPEM string
|
|
PresetAmountsFen []int64
|
|
MinAmountFen, MaxAmountFen int64
|
|
OrderTTL time.Duration
|
|
}
|
|
|
|
type Options struct {
|
|
Enabled bool `json:"enabled"`
|
|
CanRecharge bool `json:"canRecharge"`
|
|
PresetAmountsFen []int64 `json:"presetAmountsFen"`
|
|
MinAmountFen int64 `json:"minAmountFen"`
|
|
MaxAmountFen int64 `json:"maxAmountFen"`
|
|
}
|