Skip to content

Commit

Permalink
feat: 添加部分 api
Browse files Browse the repository at this point in the history
  • Loading branch information
taydy committed Oct 24, 2019
1 parent a26e29c commit 8fb7ab5
Show file tree
Hide file tree
Showing 12 changed files with 351 additions and 37 deletions.
5 changes: 2 additions & 3 deletions client/alipay_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/taydy/pay/constant"
"github.com/taydy/pay/struct"
"github.com/taydy/pay/util"
"time"
)

/** 阿里 Wap 支付客户端。 */
Expand All @@ -20,7 +19,7 @@ func (c *AliAppPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
m.AppId = c.AppID
m.Method = constant.ALI_PAY_API_APP_PAY
m.Charset = constant.CHARSET_UTF8
m.Timestamp = time.Now().Format(constant.TIME_FORMAT)
m.Timestamp = util.DongBaTime().Format(constant.TIME_FORMAT)
m.Version = "1.0"
m.NotifyUrl = charge.NotifyUrl

Expand All @@ -29,7 +28,7 @@ func (c *AliAppPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
bizContent.ProductCode = constant.ALI_PAY_PRODUCT_CODE_MSECURITY
bizContent.TotalAmount = util.CentsToYuan(charge.TotalFee)
bizContent.Subject = charge.Body
bizContent.TimeExpire = time.Now().Add(constant.TIMEOUT_PAY).Format(constant.EXPIRE_TIME_FORMAT)
bizContent.TimeExpire = util.DongBaTime().Add(constant.TIMEOUT_PAY).Format(constant.EXPIRE_TIME_FORMAT)
bizContent.TimeoutExpress = fmt.Sprintf("%.fm", constant.TIMEOUT_PAY.Minutes())

bizContentByte, _ := json.Marshal(bizContent)
Expand Down
55 changes: 55 additions & 0 deletions client/alipay_qrcode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package client

import (
"encoding/json"
"fmt"
"github.com/fatih/structs"
"github.com/taydy/pay/constant"
_struct "github.com/taydy/pay/struct"
"github.com/taydy/pay/util"
)

/** 阿里 Wap 支付客户端。 */
type AliPayQRCodeClient struct {
*AliPayClient
}

func (c *AliPayQRCodeClient) Pay(charge *_struct.Charge) (map[string]interface{}, error) {
var m = &_struct.AliPayUnifiedOrder{}
m.AppId = c.AppID
m.Method = constant.ALI_PAY_API_PRE_CREATE
m.Charset = constant.CHARSET_UTF8
m.Timestamp = util.DongBaTime().Format(constant.TIME_FORMAT)
m.Version = "1.0"
m.NotifyUrl = charge.NotifyUrl

var bizContent = &_struct.BizContent{}
bizContent.OutTradeNo = charge.OutTradeNo
bizContent.ProductCode = constant.ALI_PAY_PRODUCT_DACE_TO_FACE_PAYMENT
bizContent.TotalAmount = util.CentsToYuan(charge.TotalFee)
bizContent.Subject = charge.Body
//bizContent.TimeExpire = util.DongBaTime().Add(constant.TIMEOUT_PAY).Format(constant.EXPIRE_TIME_FORMAT)
bizContent.QRCodeTimeoutExpress = fmt.Sprintf("%.fm", constant.TIMEOUT_PAY.Minutes())

bizContentByte, _ := json.Marshal(bizContent)
m.BizContent = string(bizContentByte)

m.SignType = constant.SIGN_TYPE_RSA2
m.Sign = util.AliSign(structs.Map(m), c.PrivateKey)

payResult, err := c.TradePrecreate(m)
if err != nil {
return nil, err
}

return map[string]interface{}{
"out_trade_no": payResult.AlipayTradePrecreateResponse.OutTradeNo,
"qr_code": payResult.AlipayTradePrecreateResponse.QRCode,
}, nil
}

func (c *AliPayQRCodeClient) PayToClient(charge *_struct.Charge) (map[string]interface{}, error) {
panic("implement me")
}

var _ PayClient = &AliPayQRCodeClient{}
5 changes: 2 additions & 3 deletions client/alipay_wap.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/taydy/pay/constant"
"github.com/taydy/pay/struct"
"github.com/taydy/pay/util"
"time"
)

/** 阿里 Wap 支付客户端。 */
Expand All @@ -21,7 +20,7 @@ func (c *AliWapPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
m.AppId = c.AppID
m.Method = constant.ALI_PAY_API_WAP_PAY
m.Charset = constant.CHARSET_UTF8
m.Timestamp = time.Now().Format(constant.TIME_FORMAT)
m.Timestamp = util.DongBaTime().Format(constant.TIME_FORMAT)
m.Version = "1.0"
m.NotifyUrl = charge.NotifyUrl
m.ReturnUrl = charge.ReturnUrl
Expand All @@ -31,7 +30,7 @@ func (c *AliWapPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
bizContent.ProductCode = constant.ALI_PAY_PRODUCT_CODE_WAP
bizContent.TotalAmount = util.CentsToYuan(charge.TotalFee)
bizContent.Subject = charge.Body
bizContent.TimeExpire = time.Now().Add(constant.TIMEOUT_PAY).Format(constant.EXPIRE_TIME_FORMAT)
bizContent.TimeExpire = util.DongBaTime().Add(constant.TIMEOUT_PAY).Format(constant.EXPIRE_TIME_FORMAT)
bizContent.TimeoutExpress = fmt.Sprintf("%.fm", constant.TIMEOUT_PAY.Minutes())

bizContentByte, _ := json.Marshal(bizContent)
Expand Down
5 changes: 2 additions & 3 deletions client/alipay_web.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/taydy/pay/constant"
"github.com/taydy/pay/struct"
"github.com/taydy/pay/util"
"time"
)

/** 阿里 Web 支付客户端。 */
Expand All @@ -24,7 +23,7 @@ func (c *AliWebPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
m.AppId = c.AppID
m.Method = constant.ALI_PAY_API_PAGE_PAY
m.Charset = constant.CHARSET_UTF8
m.Timestamp = time.Now().Format(constant.TIME_FORMAT)
m.Timestamp = util.DongBaTime().Format(constant.TIME_FORMAT)
m.Version = "1.0"
m.NotifyUrl = charge.NotifyUrl
m.ReturnUrl = charge.ReturnUrl
Expand All @@ -34,7 +33,7 @@ func (c *AliWebPayClient) Pay(charge *_struct.Charge) (map[string]interface{}, e
bizContent.ProductCode = constant.ALI_PAY_PRODUCT_CODE_INSTANT
bizContent.TotalAmount = util.CentsToYuan(charge.TotalFee)
bizContent.Subject = charge.Body
bizContent.TimeExpire = time.Now().Add(constant.TIMEOUT_PAY).Format(constant.TIME_FORMAT)
bizContent.TimeExpire = util.DongBaTime().Add(constant.TIMEOUT_PAY).Format(constant.TIME_FORMAT)
bizContent.TimeoutExpress = fmt.Sprintf("%.fm", constant.TIMEOUT_PAY.Minutes())
bizContent.QrPayMode = constant.QR_PAY_MOD_IFRAME

Expand Down
83 changes: 83 additions & 0 deletions client/alipayclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/taydy/pay/struct"
"github.com/taydy/pay/util"
"io/ioutil"
"log"
"net/http"
"net/url"
"sort"
Expand All @@ -33,6 +34,36 @@ func (c *AliPayClient) UnifiedOrder(unifiedOrder *_struct.AliPayUnifiedOrder) (m
return map[string]interface{}{"url": url}, nil
}

func (c *AliPayClient) TradePrecreate(unifiedOrder *_struct.AliPayUnifiedOrder) (*_struct.AlipayTradePrecreateResponse, error) {
url := ToURL(constant.ALI_PAY_GATEWAY, structs.Map(unifiedOrder))
fmt.Printf("ali pay trade precreate order url : %s \n", url)

resp, err := http.Get(url)
if err != nil {
fmt.Printf("alipay unified order error: %v \n", err)
return nil, payErrors.ErrAlipayError
}

defer resp.Body.Close()

data, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("ali pay order query response: %s \n", string(data))

err = c.validResult(data, constant.ALI_PAY_TRADE_PRECREATE_RESPONSE)
if err != nil {
return nil, err
}

payResult := &_struct.AlipayTradePrecreateResponse{}
decodeErr := json.Unmarshal(data, payResult)
if decodeErr != nil {
fmt.Printf("alipay order query error, error: %v \n", decodeErr)
return nil, payErrors.ErrAlipayError
}

return payResult, nil
}

/**
* 订单查询。
*/
Expand Down Expand Up @@ -213,7 +244,12 @@ func (c *AliPayClient) validResult(data []byte, responseKey string) error {
return nil
}

func (c *AliPayClient) ValidAsyncResultByStruct(PayNotifyResult *_struct.ALIPayNotifyResult) bool {
return c.ValidAsyncResult(structs.Map(PayNotifyResult))
}

func (c *AliPayClient) ValidAsyncResult(params map[string]interface{}) bool {
log.Println(params)
var keys []string
var origin []string

Expand All @@ -232,6 +268,53 @@ func (c *AliPayClient) ValidAsyncResult(params map[string]interface{}) bool {
return util.ValidAliSign(str, params["sign"].(string), c.PublicKey)
}

/**
* 退款。
*/
func (c *AliPayClient) Refund(tradeNo string, refundFee int) (bool, error) {
bizContent := make(map[string]interface{})
bizContent["trade_no"] = tradeNo
bizContent["refund_amount"] = util.CentsToYuan(refundFee)
bizContentByte, _ := json.Marshal(bizContent)
refundReq := map[string]interface{}{
"app_id": c.AppID,
"method": constant.ALI_PAY_API_REFUND,
"charset": "UTF-8",
"sign_type": "RSA2",
"timestamp": time.Now().Format(constant.TIME_FORMAT),
"version": "1.0",
"biz_content": string(bizContentByte),
}
refundReq["sign"] = util.AliSign(refundReq, c.PrivateKey)

url := ToURL(constant.ALI_PAY_GATEWAY, refundReq)

resp, err := http.Get(url)
if err != nil {
fmt.Printf("alipay refund %s error: %v \n", tradeNo, err)
return false, payErrors.ErrAlipayCloseOrderError
}

defer resp.Body.Close()

data, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("ali pay refund %s query response: %s \n", tradeNo, string(data))

err = c.validResult(data, constant.ALI_PAY_TRADE_REFUND_RESPONSE)
if err != nil {
return false, err
}

refundResult := &_struct.AliTradeRefundResult{}
decodeErr := json.Unmarshal(data, refundResult)
if decodeErr != nil {
fmt.Printf("alipay refund order query error, error: %v \n", decodeErr)
return false, payErrors.ErrAlipayError
}

return util.RefundSuccess(refundResult), nil
}

/**
* 生成蚂蚁金服支付接口连接。
*/
Expand Down
47 changes: 40 additions & 7 deletions client/wechatclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type WeChatClient struct {
SecretKey string // 密钥
PrivateKey string // 私钥文件内容
PublicKey string // 公钥文件内容
TLSConfig *tls.Config
}

/**
Expand Down Expand Up @@ -61,20 +62,15 @@ func (c *WeChatClient) OrderQuery(unifiedOrder *_struct.WeChatUnifiedOrder) (*_s
return c.validResult(data)
}

func (c *WeChatClient) OrderQueryByOutTradeNo(outTradeNo string) (map[string]interface{}, error) {
func (c *WeChatClient) OrderQueryByOutTradeNo(outTradeNo string) (*_struct.WeChatPayResult, error) {
unifiedOrder := _struct.WeChatUnifiedOrder{}
unifiedOrder.Appid = c.AppID
unifiedOrder.MchId = c.MchID
unifiedOrder.OutTradeNo = outTradeNo
unifiedOrder.NonceStr = util.RandomStr()
unifiedOrder.Sign = util.WeChatSign(structs.Map(unifiedOrder), c.SecretKey)

result, err := c.OrderQuery(&unifiedOrder)
if err != nil {
return nil, err
}

return structs.Map(result), nil
return c.OrderQuery(&unifiedOrder)
}

/**
Expand Down Expand Up @@ -199,3 +195,40 @@ func (c *WeChatClient) SnsOauthAccessToken(code string) (*_struct.WeChatSnsOauth
}
return oauth, nil
}

/**
* 退款。
*/
func (c *WeChatClient) Refund(tradeNo string, refundFee int) (bool, error) {
refundReq := &_struct.WXRefundReq{
AppID: c.AppID,
MchID: c.MchID,
NonceStr: util.RandomStr(),
TotalFee: refundFee,
OutRefundNo: tradeNo,
TransactionID: tradeNo,
RefundFee: refundFee,
}
refundReq.Sign = util.WeChatSign(structs.Map(refundReq), c.SecretKey)
xmlResponse, err := http.XmlSecurePost(constant.WECHAT_PAY_REFUND, refundReq, time.Second*10, c.TLSConfig)
if err != nil {
fmt.Printf("wechat refund order error: %v \n", err)
return false, payErrors.ErrWXPayError
}

defer xmlResponse.Body.Close()

data, _ := ioutil.ReadAll(xmlResponse.Body)
fmt.Printf("wechat refund query response: %s \n", data)

payResult := &_struct.WXRefundResp{}
decodeErr := xml.Unmarshal(data, payResult)
if decodeErr != nil {
fmt.Printf("wechat transfer error, error: %v \n", decodeErr)
return false, payErrors.ErrWXPayError
}
if payResult.ReturnCode == constant.SUCCESS || payResult.ResultCode == constant.SUCCESS {
return true, nil
}
return false, payErrors.NewBadRequestError(payErrors.WX_PAY_ERROR, payResult.ErrCodeDes)
}
10 changes: 7 additions & 3 deletions constant/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const (
ALI_PAY_API_PAGE_PAY = "alipay.trade.page.pay" // 统一收单下单并支付页面接口 https://docs.open.alipay.com/api_1/alipay.trade.page.pay/
ALI_PAY_API_WAP_PAY = "alipay.trade.wap.pay" // 手机端统一下单接口
ALI_PAY_API_APP_PAY = "alipay.trade.app.pay" // app 端统一下单
ALI_PAY_API_PRE_CREATE = "alipay.trade.precreate" // 统一收单线下交易预创建(扫码支付)
ALI_PAY_API_QUERY = "alipay.trade.query" // 统一收单线下交易查询接口 https://docs.open.alipay.com/api_1/alipay.trade.query
ALI_PAY_API_REFUND = "alipay.trade.refund" // 统一收单交易退款接口 https://docs.open.alipay.com/api_1/alipay.trade.refund
ALI_PAY_API_REFUND_QUERY = "alipay.trade.fastpay.refund.query" // 统一收单交易退款查询接口 https://docs.open.alipay.com/api_1/alipay.trade.fastpay.refund.query
Expand All @@ -47,12 +48,15 @@ const (
ALI_PAY_FUND_TRANS_TO_ACCOUNT_TRANSFER_RESPONSE = "alipay_fund_trans_toaccount_transfer_response"
ALI_PAY_TRADE_QUERY_RESPONSE = "alipay_trade_query_response"
ALI_PAY_TRADE_CLOSE_RESPONSE = "alipay_trade_close_response"
ALI_PAY_TRADE_PRECREATE_RESPONSE = "alipay_trade_precreate_response"
ALI_PAY_TRADE_REFUND_RESPONSE = "alipay_trade_refund_response"
)

const (
ALI_PAY_PRODUCT_CODE_WAP = "QUICK_WAP_WAY"
ALI_PAY_PRODUCT_CODE_MSECURITY = "QUICK_MSECURITY_PAY"
ALI_PAY_PRODUCT_CODE_INSTANT = "FAST_INSTANT_TRADE_PAY"
ALI_PAY_PRODUCT_CODE_WAP = "QUICK_WAP_WAY"
ALI_PAY_PRODUCT_CODE_MSECURITY = "QUICK_MSECURITY_PAY"
ALI_PAY_PRODUCT_CODE_INSTANT = "FAST_INSTANT_TRADE_PAY"
ALI_PAY_PRODUCT_DACE_TO_FACE_PAYMENT = "FACE_TO_FACE_PAYMENT"
)

const (
Expand Down
1 change: 1 addition & 0 deletions constant/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const (
WECHAT_PAY_UNIFIED_ORDER = WECHAT_PAY_ROOT + "/pay/unifiedorder"
WECHAT_PAY_ORDER_QUERY = WECHAT_PAY_ROOT + "/pay/orderquery"
WECHAT_PAY_CLOSE_ORDER = WECHAT_PAY_ROOT + "/pay/closeorder"
WECHAT_PAY_REFUND = WECHAT_PAY_ROOT + "/secapi/pay/refund"
WECHAT_PAY_REFUND_QUERY = WECHAT_PAY_ROOT + "/pay/refundquery"
WECHAT_PAY_TRANSFER = WECHAT_PAY_ROOT + "/mmpaymkttransfers/promotion/transfers"
WECHAT_SNS_OAUTH2 = "https://api.weixin.qq.com/sns/oauth2/access_token"
Expand Down
Loading

0 comments on commit 8fb7ab5

Please sign in to comment.