feat: add refund statuses
This commit is contained in:
@@ -40,45 +40,19 @@ type PayNotify struct {
|
||||
} `json:"amount"`
|
||||
}
|
||||
|
||||
type RefundResponse struct {
|
||||
RefundID string `json:"refund_id"`
|
||||
OutRefundNo string `json:"out_refund_no"`
|
||||
type RefundNotify struct {
|
||||
Mchid string `json:"mchid"`
|
||||
TransactionID string `json:"transaction_id"`
|
||||
OutTradeNo string `json:"out_trade_no"`
|
||||
Channel string `json:"channel"`
|
||||
UserReceivedAccount string `json:"user_received_account"`
|
||||
RefundID string `json:"refund_id"`
|
||||
OutRefundNo string `json:"out_refund_no"`
|
||||
RefundStatus string `json:"refund_status"`
|
||||
SuccessTime time.Time `json:"success_time"`
|
||||
CreateTime time.Time `json:"create_time"`
|
||||
Status string `json:"status"`
|
||||
FundsAccount string `json:"funds_account"`
|
||||
UserReceivedAccount string `json:"user_received_account"`
|
||||
Amount struct {
|
||||
Total int `json:"total"`
|
||||
Refund int `json:"refund"`
|
||||
From []struct {
|
||||
Account string `json:"account"`
|
||||
Amount int `json:"amount"`
|
||||
} `json:"from"`
|
||||
PayerTotal int `json:"payer_total"`
|
||||
PayerRefund int `json:"payer_refund"`
|
||||
SettlementRefund int `json:"settlement_refund"`
|
||||
SettlementTotal int `json:"settlement_total"`
|
||||
DiscountRefund int `json:"discount_refund"`
|
||||
Currency string `json:"currency"`
|
||||
RefundFee int `json:"refund_fee"`
|
||||
Total int `json:"total"`
|
||||
Refund int `json:"refund"`
|
||||
PayerTotal int `json:"payer_total"`
|
||||
PayerRefund int `json:"payer_refund"`
|
||||
} `json:"amount"`
|
||||
PromotionDetail []struct {
|
||||
PromotionID string `json:"promotion_id"`
|
||||
Scope string `json:"scope"`
|
||||
Type string `json:"type"`
|
||||
Amount int `json:"amount"`
|
||||
RefundAmount int `json:"refund_amount"`
|
||||
GoodsDetail []struct {
|
||||
MerchantGoodsID string `json:"merchant_goods_id"`
|
||||
WechatpayGoodsID string `json:"wechatpay_goods_id"`
|
||||
GoodsName string `json:"goods_name"`
|
||||
UnitPrice int `json:"unit_price"`
|
||||
RefundAmount int `json:"refund_amount"`
|
||||
RefundQuantity int `json:"refund_quantity"`
|
||||
} `json:"goods_detail"`
|
||||
} `json:"promotion_detail"`
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ type PrepayData struct {
|
||||
}
|
||||
|
||||
// PaySignOfJSAPI
|
||||
func (pay *PrepayData) PaySignOfJSAPI() (*, error) {
|
||||
func (pay *PrepayData) PaySignOfJSAPI() (*wechat.JSAPIPayParams, error) {
|
||||
return pay.client.payClient.PaySignOfJSAPI(pay.AppID, pay.PrepayID)
|
||||
}
|
||||
|
||||
func (c *Client) Refund(ctx context.Context, f func(*BodyMap)) (*wechat.RefundOrderResponse,error ){
|
||||
func (c *Client) Refund(ctx context.Context, f func(*BodyMap)) (*wechat.RefundOrderResponse, error) {
|
||||
bm := NewBodyMap(c.config)
|
||||
f(bm)
|
||||
|
||||
@@ -117,7 +117,11 @@ func (c *Client) V3TransactionJsapi(ctx context.Context, f func(*BodyMap)) (*Pre
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Client) ParseNotify(ctx fiber.Ctx) (*PayNotify, error) {
|
||||
func (c *Client) ParseNotify(
|
||||
ctx fiber.Ctx,
|
||||
payCallback func(fiber.Ctx, *wechat.V3DecryptPayResult) error,
|
||||
refundCallback func(fiber.Ctx, *wechat.V3DecryptRefundResult) error,
|
||||
) error {
|
||||
body := ctx.Body()
|
||||
si := &wechat.SignInfo{
|
||||
HeaderTimestamp: ctx.Get(wechat.HeaderTimestamp),
|
||||
@@ -126,31 +130,54 @@ func (c *Client) ParseNotify(ctx fiber.Ctx) (*PayNotify, error) {
|
||||
HeaderSerial: ctx.Get(wechat.HeaderSerial),
|
||||
SignBody: string(body),
|
||||
}
|
||||
|
||||
notifyReq := &wechat.V3NotifyReq{SignInfo: si}
|
||||
if err := js.UnmarshalBytes(body, notifyReq); err != nil {
|
||||
log.Errorf("json unmarshal error:%v", err)
|
||||
return nil, ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": fmt.Sprintf("json unmarshal error:%v", err)})
|
||||
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": fmt.Sprintf("json unmarshal error:%v", err)})
|
||||
}
|
||||
|
||||
// 获取微信平台证书
|
||||
certMap := c.WxPublicKeyMap()
|
||||
|
||||
// 验证异步通知的签名
|
||||
err := notifyReq.VerifySignByPKMap(certMap)
|
||||
if err != nil {
|
||||
if err := notifyReq.VerifySignByPKMap(certMap); err != nil {
|
||||
log.Errorf("verify sign error:%v", err)
|
||||
return nil, ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid signature"})
|
||||
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid signature"})
|
||||
}
|
||||
|
||||
var notifyData PayNotify
|
||||
err = notifyReq.DecryptCipherTextToStruct(c.config.Pay.ApiV3Key, ¬ifyData)
|
||||
if err != nil {
|
||||
return nil, ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid cipher text"})
|
||||
// TRANSACTION.SUCCESS :支付成功通知
|
||||
// REFUND.SUCCESS:退款成功通知
|
||||
// REFUND.ABNORMAL:退款异常通知
|
||||
// REFUND.CLOSED:退款关闭通知
|
||||
switch notifyReq.EventType {
|
||||
case "TRANSACTION.SUCCESS":
|
||||
var notifyData wechat.V3DecryptPayResult
|
||||
if err := notifyReq.DecryptCipherTextToStruct(c.config.Pay.ApiV3Key, ¬ifyData); err != nil {
|
||||
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid cipher text"})
|
||||
}
|
||||
log.Infof("Successfully decrypted cipher text for pay notify data: %+v", notifyData)
|
||||
if err := payCallback(ctx, ¬ifyData); err != nil {
|
||||
log.Errorf("payCallback error:%v", err)
|
||||
return err
|
||||
}
|
||||
case "REFUND.SUCCESS", "REFUND.ABNORMAL", "REFUND.CLOSED":
|
||||
var notifyData wechat.V3DecryptRefundResult
|
||||
if err := notifyReq.DecryptCipherTextToStruct(c.config.Pay.ApiV3Key, ¬ifyData); err != nil {
|
||||
return ctx.Status(http.StatusBadRequest).JSON(fiber.Map{"error": "Invalid cipher text"})
|
||||
}
|
||||
log.Infof("Successfully decrypted cipher text for refund notify data: %+v", notifyData)
|
||||
|
||||
if err := refundCallback(ctx, ¬ifyData); err != nil {
|
||||
log.Errorf("refundCallback error:%v", err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("Successfully decrypted cipher text for notify data: %+v", notifyData)
|
||||
|
||||
return ¬ifyData, nil
|
||||
return ctx.Status(http.StatusOK).JSON(&wechat.V3NotifyRsp{
|
||||
Code: gopay.SUCCESS,
|
||||
Message: "成功",
|
||||
})
|
||||
}
|
||||
|
||||
type BodyMap struct {
|
||||
|
||||
Reference in New Issue
Block a user