You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.9 KiB
117 lines
2.9 KiB
package wxpay
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"encoding/xml"
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/nanjishidu/gomini/gocrypto"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"recook/internal/v2/logic/pay"
|
|
"recook/tools"
|
|
"strings"
|
|
)
|
|
|
|
/*
|
|
<xml>
|
|
<return_code>SUCCESS</return_code>
|
|
<appid><![CDATA[wx2421b1c4370ec43b]]></appid>
|
|
<mch_id><![CDATA[10000100]]></mch_id>
|
|
<nonce_str><![CDATA[TeqClE3i0mvn3DrK]]></nonce_str>
|
|
<req_info><![CDATA[T87GAHG17TGAHG1TGHAHAHA1Y1CIOA9UGJH1GAHV871HAGAGQYQQPOOJMXNBCXBVNMNMAJAA]]></req_info>
|
|
</xml>
|
|
*/
|
|
|
|
/*
|
|
<root>
|
|
<out_refund_no><![CDATA[131811191610442717309]]></out_refund_no>
|
|
<out_trade_no><![CDATA[71106718111915575302817]]></out_trade_no>
|
|
<refund_account><![CDATA[REFUND_SOURCE_RECHARGE_FUNDS]]></refund_account>
|
|
<refund_fee><![CDATA[3960]]></refund_fee>
|
|
<refund_id><![CDATA[50000408942018111907145868882]]></refund_id>
|
|
<refund_recv_accout><![CDATA[支付用户零钱]]></refund_recv_accout>
|
|
<refund_request_source><![CDATA[API]]></refund_request_source>
|
|
<refund_status><![CDATA[SUCCESS]]></refund_status>
|
|
<settlement_refund_fee><![CDATA[3960]]></settlement_refund_fee>
|
|
<settlement_total_fee><![CDATA[3960]]></settlement_total_fee>
|
|
<success_time><![CDATA[2018-11-19 16:24:13]]></success_time>
|
|
<total_fee><![CDATA[3960]]></total_fee>
|
|
<transaction_id><![CDATA[4200000215201811190261405420]]></transaction_id>
|
|
</root>
|
|
*/
|
|
|
|
type RefundCallbackNotification struct {
|
|
XMLName xml.Name `xml:"xml"`
|
|
AppID string `xml:"appid"`
|
|
MchId string `xml:"mch_id"` // 商户号
|
|
NonceStr string `xml:"nonce_str"` // 随机字符串
|
|
ReqInfo string `xml:"req_info"`
|
|
}
|
|
|
|
type RefundReqInfo struct {
|
|
XMLName xml.Name `xml:"root"`
|
|
OutRefundNo string `xml:"out_refund_no"`
|
|
RefundFee uint `xml:"refund_fee"`
|
|
RefundStatus string `xml:"refund_status"`
|
|
SuccessTime string `xml:"success_time"`
|
|
}
|
|
|
|
func (r *RefundReqInfo) IsOk() bool {
|
|
return r.RefundStatus == "SUCCESS"
|
|
}
|
|
|
|
func RefundCallback(c *gin.Context) {
|
|
FAIL := gin.H{
|
|
"return_code": "FAIL",
|
|
"return_msg": "OK",
|
|
}
|
|
SUCCESS := gin.H{
|
|
"return_code": "SUCCESS",
|
|
"return_msg": "OK",
|
|
}
|
|
|
|
body, err := ioutil.ReadAll(c.Request.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
var notification RefundCallbackNotification
|
|
err = xml.Unmarshal(body, ¬ification)
|
|
if err != nil {
|
|
log.Println(err)
|
|
c.XML(http.StatusOK, FAIL)
|
|
return
|
|
}
|
|
|
|
_ = gocrypto.SetAesKey(strings.ToLower(tools.MD5(APIKey)))
|
|
str, _ := base64.StdEncoding.DecodeString(notification.ReqInfo)
|
|
deBody, err := gocrypto.AesECBDecrypt(str)
|
|
if err != nil {
|
|
log.Println(err)
|
|
c.XML(http.StatusOK, FAIL)
|
|
return
|
|
}
|
|
|
|
var info RefundReqInfo
|
|
err = xml.Unmarshal(deBody, &info)
|
|
if err != nil {
|
|
log.Println(err)
|
|
c.XML(http.StatusOK, FAIL)
|
|
return
|
|
}
|
|
|
|
if info.IsOk() == false {
|
|
log.Println(info)
|
|
c.XML(http.StatusOK, FAIL)
|
|
return
|
|
}
|
|
|
|
if err = pay.AsyncRefundSuccessCallback(info.OutRefundNo); err != nil {
|
|
log.Println(err)
|
|
c.XML(http.StatusOK, FAIL)
|
|
return
|
|
}
|
|
|
|
c.XML(http.StatusOK, SUCCESS)
|
|
}
|