支付宝转账
This commit is contained in:
parent
d64c0d0e33
commit
1bc256fc19
|
@ -20,6 +20,7 @@ const (
|
||||||
const baseUri = "https://openapi.alipay.com/gateway.do"
|
const baseUri = "https://openapi.alipay.com/gateway.do"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// 支持幂等请求
|
||||||
orderMethod = "alipay.fund.trans.uni.transfer"
|
orderMethod = "alipay.fund.trans.uni.transfer"
|
||||||
queryMethod = "alipay.fund.trans.common.query"
|
queryMethod = "alipay.fund.trans.common.query"
|
||||||
)
|
)
|
||||||
|
@ -44,7 +45,7 @@ func (s *AlipayRedPackService) Order(ctx context.Context, request *proto.OrderRe
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var response po.OrderResp
|
var response po.OrderResp
|
||||||
err = requests.URL(baseUri).Post().BodyForm(uv).ToJSON(&response).Fetch(ctx)
|
err = requests.URL(baseUri).Post().Params(uv).ToJSON(&response).Fetch(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
return nil, fmt.Errorf("请求异常,msg:" + err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestOrder(t *testing.T) {
|
||||||
request := &proto.OrderRequest{
|
request := &proto.OrderRequest{
|
||||||
Config: config(),
|
Config: config(),
|
||||||
Order: &proto.OrderRequest_Order{
|
Order: &proto.OrderRequest_Order{
|
||||||
OrderNo: "lsxd202306071545141533",
|
OrderNo: "lsxd202406071545141533",
|
||||||
Account: "18666173766",
|
Account: "18666173766",
|
||||||
Quantity: 1,
|
Quantity: 1,
|
||||||
Amount: 0.01,
|
Amount: 0.01,
|
||||||
|
@ -44,7 +44,7 @@ func TestOrder(t *testing.T) {
|
||||||
Product: &proto.OrderRequest_Product{
|
Product: &proto.OrderRequest_Product{
|
||||||
ProductNo: "",
|
ProductNo: "",
|
||||||
Price: 0.01,
|
Price: 0.01,
|
||||||
Extra: []byte(`{"wishing":"祝福语"}`),
|
Extra: []byte(`{"wishing":"zhufuyu"}`),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
t.Run("TestOrder", func(t *testing.T) {
|
t.Run("TestOrder", func(t *testing.T) {
|
||||||
|
|
|
@ -14,7 +14,7 @@ type PayeeInfo struct {
|
||||||
|
|
||||||
type OrderReq struct {
|
type OrderReq struct {
|
||||||
OutBizNo string `validate:"required" json:"out_biz_no"`
|
OutBizNo string `validate:"required" json:"out_biz_no"`
|
||||||
TransAmount string `validate:"required" json:"trans_amount"`
|
TransAmount float32 `validate:"required" json:"trans_amount"`
|
||||||
ProductCode string `validate:"required" json:"product_code"`
|
ProductCode string `validate:"required" json:"product_code"`
|
||||||
BizScene string `validate:"required" json:"biz_scene"`
|
BizScene string `validate:"required" json:"biz_scene"`
|
||||||
OrderTitle string `json:"order_title"`
|
OrderTitle string `json:"order_title"`
|
||||||
|
@ -33,13 +33,14 @@ type OrderResponse struct {
|
||||||
OrderId string `json:"order_id"`
|
OrderId string `json:"order_id"`
|
||||||
PayFundOrderId string `json:"pay_fund_order_id"`
|
PayFundOrderId string `json:"pay_fund_order_id"`
|
||||||
Status string `json:"status"`
|
Status string `json:"status"`
|
||||||
TransDate int32 `json:"trans_date"`
|
TransDate string `json:"trans_date"`
|
||||||
SettleSerialNo int32 `json:"settle_serial_no"`
|
SettleSerialNo int32 `json:"settle_serial_no"` // 清算机构流水号
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderResp struct {
|
type OrderResp struct {
|
||||||
Response OrderResponse `json:"alipay_fund_trans_uni_transfer_response"`
|
Response OrderResponse `json:"alipay_fund_trans_uni_transfer_response"`
|
||||||
Sign string `json:"sign"`
|
AlipayCertSn string `json:"alipay_cert_sn"`
|
||||||
|
Sign string `json:"sign"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *OrderResp) GetMsg() string {
|
func (o *OrderResp) GetMsg() string {
|
||||||
|
|
|
@ -89,7 +89,7 @@ func orderReq(order *proto.OrderRequest_Order, product *proto.OrderRequest_Produ
|
||||||
|
|
||||||
o := &po.OrderReq{
|
o := &po.OrderReq{
|
||||||
OutBizNo: order.OrderNo,
|
OutBizNo: order.OrderNo,
|
||||||
TransAmount: fmt.Sprintf("%.2f", order.Amount),
|
TransAmount: order.Amount,
|
||||||
ProductCode: "STD_RED_PACKET",
|
ProductCode: "STD_RED_PACKET",
|
||||||
BizScene: "DIRECT_TRANSFER",
|
BizScene: "DIRECT_TRANSFER",
|
||||||
OrderTitle: productExtra.Wishing,
|
OrderTitle: productExtra.Wishing,
|
||||||
|
|
|
@ -18,17 +18,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func isValidPhoneNumber(phoneNumber string) bool {
|
func isValidPhoneNumber(phoneNumber string) bool {
|
||||||
// 定义中国大陆手机号的正则表达式
|
|
||||||
// 这个正则表达式匹配11位数字,以1开头,第二位为3、4、5、7、8中的一个,后面跟任意8位数字
|
|
||||||
phoneRegex := `^1[34578]\d{9}$`
|
phoneRegex := `^1[34578]\d{9}$`
|
||||||
// 使用正则表达式进行匹配
|
|
||||||
return regexp.MustCompile(phoneRegex).MatchString(phoneNumber)
|
return regexp.MustCompile(phoneRegex).MatchString(phoneNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isEmailValid(email string) bool {
|
func isEmailValid(email string) bool {
|
||||||
// 定义邮箱的正则表达式
|
|
||||||
var emailRegex = regexp.MustCompile(`[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
var emailRegex = regexp.MustCompile(`[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
||||||
// 使用正则表达式匹配邮箱地址
|
|
||||||
return emailRegex.MatchString(email)
|
return emailRegex.MatchString(email)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,16 +32,14 @@ func req(config *Config, req *po.Param) (url.Values, error) {
|
||||||
uv := url.Values{}
|
uv := url.Values{}
|
||||||
kvRows := utils.SortStructJsonTag(req)
|
kvRows := utils.SortStructJsonTag(req)
|
||||||
for _, kv := range kvRows {
|
for _, kv := range kvRows {
|
||||||
if kv.Key == "sign" {
|
if kv.Key == "sign" || kv.Value == "" {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if kv.Value == "" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
uv.Set(kv.Key, kv.Value)
|
uv.Set(kv.Key, kv.Value)
|
||||||
strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
|
strToBeSigned.WriteString(fmt.Sprintf("%s=%s&", kv.Key, kv.Value))
|
||||||
}
|
}
|
||||||
s := strings.TrimRight(strToBeSigned.String(), "&")
|
s := strings.TrimRight(strToBeSigned.String(), "&")
|
||||||
|
|
||||||
sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk)))
|
sign, err := Sign(s, []byte(utils.NewPrivate().Build(config.Prk)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -81,13 +74,7 @@ func Verify(n *po.Notify, publicKeyPEM string) (bool, error) {
|
||||||
uv := url.Values{}
|
uv := url.Values{}
|
||||||
kvRows := utils.SortStructJsonTag(n)
|
kvRows := utils.SortStructJsonTag(n)
|
||||||
for _, kv := range kvRows {
|
for _, kv := range kvRows {
|
||||||
if kv.Key == "sign" {
|
if kv.Key == "sign" || kv.Key == "sign_type" || kv.Value == "" {
|
||||||
continue
|
|
||||||
}
|
|
||||||
if kv.Key == "sign_type" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if kv.Value == "" {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
uv.Set(kv.Key, kv.Value)
|
uv.Set(kv.Key, kv.Value)
|
||||||
|
|
Loading…
Reference in New Issue