feat: support expiring cashier sessions
This commit is contained in:
@@ -53,12 +53,14 @@ func main() {
|
|||||||
ClientType: "pc",
|
ClientType: "pc",
|
||||||
NotifyURL: "https://merchant.example.com/pay/notify",
|
NotifyURL: "https://merchant.example.com/pay/notify",
|
||||||
ReturnURL: "https://merchant.example.com/pay/return",
|
ReturnURL: "https://merchant.example.com/pay/return",
|
||||||
|
ExpireTime: "15", // 可选,分钟数或绝对时间;默认 10 分钟
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(order.CashierURL)
|
fmt.Println(order.CashierURL)
|
||||||
|
fmt.Println(order.ExpireTime, order.PageToken)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -32,6 +32,9 @@ func TestSubmitPostsSignedForm(t *testing.T) {
|
|||||||
if params["sign_type"] != "MD5" {
|
if params["sign_type"] != "MD5" {
|
||||||
t.Fatalf("sign_type = %s", params["sign_type"])
|
t.Fatalf("sign_type = %s", params["sign_type"])
|
||||||
}
|
}
|
||||||
|
if params["expire_time"] != "15" {
|
||||||
|
t.Fatalf("expire_time = %s", params["expire_time"])
|
||||||
|
}
|
||||||
if !VerifySign(params, "secret") {
|
if !VerifySign(params, "secret") {
|
||||||
t.Fatalf("invalid sign: %s", params["sign"])
|
t.Fatalf("invalid sign: %s", params["sign"])
|
||||||
}
|
}
|
||||||
@@ -43,7 +46,9 @@ func TestSubmitPostsSignedForm(t *testing.T) {
|
|||||||
"order_no": "P123",
|
"order_no": "P123",
|
||||||
"out_trade_no": params["out_trade_no"],
|
"out_trade_no": params["out_trade_no"],
|
||||||
"amount": 100,
|
"amount": 100,
|
||||||
"cashier_url": "http://pay.test/cashier/?orderNo=P123",
|
"cashier_url": "http://pay.test/cashier/P123",
|
||||||
|
"expire_time": "2026-07-21T10:15:00+08:00",
|
||||||
|
"page_token": "page-token-1",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}))
|
}))
|
||||||
@@ -59,11 +64,12 @@ func TestSubmitPostsSignedForm(t *testing.T) {
|
|||||||
Name: "test",
|
Name: "test",
|
||||||
Money: "1.00",
|
Money: "1.00",
|
||||||
Type: "alipay",
|
Type: "alipay",
|
||||||
|
ExpireTime: "15",
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if resp.OrderNo != "P123" || resp.Amount != 100 {
|
if resp.OrderNo != "P123" || resp.Amount != 100 || resp.PageToken != "page-token-1" || resp.ExpireTime == nil {
|
||||||
t.Fatalf("unexpected response: %+v", resp)
|
t.Fatalf("unexpected response: %+v", resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ func submit(cfg globalConfig, args []string) error {
|
|||||||
fs.StringVar(&req.ReturnURL, "return-url", "", "merchant sync return URL")
|
fs.StringVar(&req.ReturnURL, "return-url", "", "merchant sync return URL")
|
||||||
fs.StringVar(&req.Body, "body", "", "order description")
|
fs.StringVar(&req.Body, "body", "", "order description")
|
||||||
fs.StringVar(&req.Attach, "attach", "", "extra data")
|
fs.StringVar(&req.Attach, "attach", "", "extra data")
|
||||||
|
fs.StringVar(&req.ExpireTime, "expire-time", "", "order lifetime in minutes or an absolute expiration time (default 10 minutes)")
|
||||||
if err := fs.Parse(args); err != nil {
|
if err := fs.Parse(args); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ type SubmitRequest struct {
|
|||||||
ReturnURL string
|
ReturnURL string
|
||||||
Body string
|
Body string
|
||||||
Attach string
|
Attach string
|
||||||
|
// ExpireTime accepts a positive lifetime in minutes, RFC3339, or YYYY-MM-DD HH:mm:ss.
|
||||||
|
// Empty uses the platform default of 10 minutes.
|
||||||
|
ExpireTime string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r SubmitRequest) params() map[string]string {
|
func (r SubmitRequest) params() map[string]string {
|
||||||
@@ -33,14 +36,17 @@ func (r SubmitRequest) params() map[string]string {
|
|||||||
"return_url": r.ReturnURL,
|
"return_url": r.ReturnURL,
|
||||||
"body": r.Body,
|
"body": r.Body,
|
||||||
"attach": r.Attach,
|
"attach": r.Attach,
|
||||||
|
"expire_time": r.ExpireTime,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type SubmitResponse struct {
|
type SubmitResponse struct {
|
||||||
OrderNo string `json:"order_no"`
|
OrderNo string `json:"order_no"`
|
||||||
OutTradeNo string `json:"out_trade_no"`
|
OutTradeNo string `json:"out_trade_no"`
|
||||||
Amount int64 `json:"amount"`
|
Amount int64 `json:"amount"`
|
||||||
CashierURL string `json:"cashier_url"`
|
CashierURL string `json:"cashier_url"`
|
||||||
|
ExpireTime *time.Time `json:"expire_time"`
|
||||||
|
PageToken string `json:"page_token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryRequest struct {
|
type QueryRequest struct {
|
||||||
@@ -64,6 +70,7 @@ type QueryResponse struct {
|
|||||||
Completed bool `json:"completed"`
|
Completed bool `json:"completed"`
|
||||||
ChannelChecked bool `json:"channel_checked"`
|
ChannelChecked bool `json:"channel_checked"`
|
||||||
PaidAt *time.Time `json:"paid_at"`
|
PaidAt *time.Time `json:"paid_at"`
|
||||||
|
ExpireTime *time.Time `json:"expire_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RefundRequest struct {
|
type RefundRequest struct {
|
||||||
@@ -128,6 +135,7 @@ type Order struct {
|
|||||||
IsManual bool `json:"is_manual"`
|
IsManual bool `json:"is_manual"`
|
||||||
PaidAt *time.Time `json:"paid_at"`
|
PaidAt *time.Time `json:"paid_at"`
|
||||||
CreatedAt *time.Time `json:"created_at"`
|
CreatedAt *time.Time `json:"created_at"`
|
||||||
|
ExpireTime *time.Time `json:"expire_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ManualRequest struct {
|
type ManualRequest struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user