voucher/internal/data/wechatrepoimpl/cpn_code.go

300 lines
12 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package wechatrepoimpl
import (
"fmt"
"strings"
"github.com/go-kratos/kratos/v2/errors"
err2 "voucher/api/err"
)
// ErrCode 定义错误码类型
// https://pay.weixin.qq.com/doc/v3/merchant/4012463767
type ErrCode string
// 定义错误码常量
const (
APPID_MCHID_NOT_MATCH ErrCode = "APPID_MCHID_NOT_MATCH"
INVALID_REQUEST ErrCode = "INVALID_REQUEST"
PARAM_ERROR ErrCode = "PARAM_ERROR"
MCH_NOT_EXISTS ErrCode = "MCH_NOT_EXISTS"
NOT_ENOUGH ErrCode = "NOT_ENOUGH"
REQUEST_BLOCKED ErrCode = "REQUEST_BLOCKED"
RULE_LIMIT ErrCode = "RULE_LIMIT"
USER_ACCOUNT_ABNORMAL ErrCode = "USER_ACCOUNT_ABNORMAL"
RESOURCE_NOT_EXISTS ErrCode = "RESOURCE_NOT_EXISTS"
FREQUENCY_LIMITED ErrCode = "FREQUENCY_LIMITED"
)
// APIError 定义 API 错误结构体
type APIError struct {
StatusCode int `json:"status_code"`
ErrorCode ErrCode `json:"error_code"`
Description string `json:"description"`
Hint string `json:"hint"`
}
// 定义错误映射,方便根据错误码获取错误信息
var _ = map[ErrCode][]APIError{
APPID_MCHID_NOT_MATCH: {
{
StatusCode: 400,
ErrorCode: APPID_MCHID_NOT_MATCH,
Description: "商户号与AppID不匹配",
Hint: "调用接口的商户号需与接口传入的AppID有绑定关系请参考常见问题Q4",
},
},
INVALID_REQUEST: {
{
StatusCode: 400,
ErrorCode: INVALID_REQUEST,
Description: "OpenID与AppID不匹配",
Hint: "OpenID与AppID需有对应关系",
},
{
StatusCode: 400,
ErrorCode: INVALID_REQUEST,
Description: "非法的商户号",
Hint: "请检查商户号准确性",
},
{
StatusCode: 400,
ErrorCode: INVALID_REQUEST,
Description: "调用频率过高",
Hint: "请降低API调用频率",
},
{
StatusCode: 400,
ErrorCode: INVALID_REQUEST,
Description: "活动已结束或未激活",
Hint: "请检查批次状态",
},
{
StatusCode: 400,
ErrorCode: INVALID_REQUEST,
Description: "批次信息获取失败,请确认参数是否有误",
Hint: "请检查创建商户号与批次号的对应关系",
},
},
PARAM_ERROR: {
{
StatusCode: 400,
ErrorCode: PARAM_ERROR,
Description: "AppID必填",
Hint: "请输入AppID",
},
{
StatusCode: 400,
ErrorCode: PARAM_ERROR,
Description: "OpenID必填",
Hint: "请输入OpenID",
},
{
StatusCode: 400,
ErrorCode: PARAM_ERROR,
Description: "批次号必填",
Hint: "请输入批次号",
},
{
StatusCode: 400,
ErrorCode: PARAM_ERROR,
Description: "商户号必填",
Hint: "请输入商户号",
},
{
StatusCode: 400,
ErrorCode: PARAM_ERROR,
Description: "非法的批次状态",
Hint: "请检查批次状态,仅支持发放状态为“运营中”的代金券批次",
},
},
MCH_NOT_EXISTS: {
{
StatusCode: 403,
ErrorCode: MCH_NOT_EXISTS,
Description: "商户号不合法",
Hint: "请检查商户号准确性",
},
},
NOT_ENOUGH: {
{
StatusCode: 403,
ErrorCode: NOT_ENOUGH,
Description: "批次预算不足",
Hint: "批次预算已发放完,请补充批次预算",
},
{
StatusCode: 403,
ErrorCode: NOT_ENOUGH,
Description: "发券超过单天限额",
Hint: "已超过该批次设置的单天发放限制额度,无法发放",
},
{
StatusCode: 403,
ErrorCode: NOT_ENOUGH,
Description: "账户余额不足,请充值",
Hint: "商户号余额不足,无法继续发券,请充值",
},
{
StatusCode: 403,
ErrorCode: NOT_ENOUGH,
Description: "批次预算耗尽",
Hint: "该批次的预算已经耗尽",
},
},
REQUEST_BLOCKED: {
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "商户无权发券",
Hint: "该批次不支持其他商户发放请参考常见问题Q1",
},
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "批次不支持跨商户发券",
Hint: "该批次不支持其他商户发放请参考常见问题Q1",
},
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "用户被限领拦截",
Hint: "该用户已达到该批次的领取上限请参考常见问题Q6",
},
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "不能在API渠道发放",
Hint: "请检查批次信息,仅支持发放微信支付代金券,不支持发放立减与折扣",
},
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "不支持指定面额发券",
Hint: "仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息",
},
{
StatusCode: 403,
ErrorCode: REQUEST_BLOCKED,
Description: "仅在广告场景下发放批次",
Hint: "该批次已在朋友圈广告发放,不支持在其他渠道发放",
},
},
RULE_LIMIT: {
{
StatusCode: 403,
ErrorCode: RULE_LIMIT,
Description: "用户已达最大领券次数",
Hint: "该用户已达到该批次的领取上限请参考常见问题Q6",
},
{
StatusCode: 403,
ErrorCode: RULE_LIMIT,
Description: "被自然人规则拦截",
Hint: "该自然人已达到该批次的领取上限请参考常见问题Q6",
},
},
USER_ACCOUNT_ABNORMAL: {
{
StatusCode: 403,
ErrorCode: USER_ACCOUNT_ABNORMAL,
Description: "用户非法",
Hint: "用户命中微信支付风控模型请参考常见问题Q5",
},
},
RESOURCE_NOT_EXISTS: {
{
StatusCode: 404,
ErrorCode: RESOURCE_NOT_EXISTS,
Description: "批次不存在",
Hint: "请检查批次及制券商户号信息",
},
},
FREQUENCY_LIMITED: {
{
StatusCode: 429,
ErrorCode: FREQUENCY_LIMITED,
Description: "当前请求人数过多,请稍后重试",
Hint: "请降低API调用频率",
},
},
}
// 使用常量定义错误描述,减少硬编码
const (
ErrorWechatUserIllegal = "用户非法"
ErrorWechatAppIDMchIDMismatch = "商户号与AppID不匹配"
ErrorWechatOpenIDAppIDMismatch = "OpenID与AppID不匹配"
ErrorWechatInvalidMerchantID = "非法的商户号"
ErrorWechatHighFrequency = "调用频率过高"
ErrorWechatActivityInactive = "活动已结束或未激活"
ErrorWechatBatchInfoError = "批次信息获取失败,请确认参数是否有误"
ErrorWechatAppIDRequired = "AppID必填"
ErrorWechatOpenIDRequired = "OpenID必填"
ErrorWechatBatchIDRequired = "批次号必填"
ErrorWechatMerchantIDRequired = "商户号必填"
ErrorWechatInvalidBatchStatus = "非法的批次状态"
ErrorWechatMchNotExists = "商户号不合法"
ErrorWechatBatchBudgetInsufficient = "批次预算不足"
ErrorWechatDailyLimitExceeded = "发券超过单天限额"
ErrorWechatAccountBalanceInsufficient = "账户余额不足,请充值"
ErrorWechatBatchBudgetDepleted = "批次预算耗尽"
ErrorWechatMerchantNoPermission = "商户无权发券"
ErrorWechatCrossMerchantNotSupported = "批次不支持跨商户发券"
ErrorWechatUserReceiveLimit = "用户被限领拦截"
ErrorWechatAPIChannelNotSupported = "不能在API渠道发放"
ErrorWechatSpecifiedDenominationNotSupported = "不支持指定面额发券"
ErrorWechatOnlyAdvertisingBatch = "仅在广告场景下发放批次"
ErrorWechatUserMaxCoupons = "用户已达最大领券次数"
ErrorWechatNaturalPersonRuleBlocked = "被自然人规则拦截"
ErrorWechatResourceNotExists = "批次不存在"
ErrorWechatFrequencyLimited = "当前请求人数过多,请稍后重试"
)
// WechatError 映射错误描述到具体的错误处理
var WechatError = map[string]*errors.Error{
ErrorWechatUserIllegal: err2.ErrorWechatUserIllegal(ErrorWechatUserIllegal),
ErrorWechatAppIDMchIDMismatch: err2.ErrorWechatAppIDMchIDMismatch(ErrorWechatAppIDMchIDMismatch),
ErrorWechatOpenIDAppIDMismatch: err2.ErrorWechatOpenIDAppIDMismatch(ErrorWechatOpenIDAppIDMismatch),
ErrorWechatInvalidMerchantID: err2.ErrorWechatInvalidMerchantID(ErrorWechatInvalidMerchantID),
ErrorWechatHighFrequency: err2.ErrorWechatHighFrequency(ErrorWechatHighFrequency),
ErrorWechatActivityInactive: err2.ErrorWechatActivityInactive(ErrorWechatActivityInactive),
ErrorWechatBatchInfoError: err2.ErrorWechatBatchInfoError(ErrorWechatBatchInfoError),
ErrorWechatAppIDRequired: err2.ErrorWechatAppIDRequired(ErrorWechatAppIDRequired),
ErrorWechatOpenIDRequired: err2.ErrorWechatOpenIDRequired(ErrorWechatOpenIDRequired),
ErrorWechatBatchIDRequired: err2.ErrorWechatBatchIDRequired(ErrorWechatBatchIDRequired),
ErrorWechatMerchantIDRequired: err2.ErrorWechatMerchantIDRequired(ErrorWechatMerchantIDRequired),
ErrorWechatInvalidBatchStatus: err2.ErrorWechatInvalidBatchStatus(ErrorWechatInvalidBatchStatus),
ErrorWechatMchNotExists: err2.ErrorWechatMchNotExists(ErrorWechatMchNotExists),
ErrorWechatBatchBudgetInsufficient: err2.ErrorWechatBatchBudgetInsufficient(ErrorWechatBatchBudgetInsufficient),
ErrorWechatDailyLimitExceeded: err2.ErrorWechatDailyLimitExceeded(ErrorWechatDailyLimitExceeded),
ErrorWechatAccountBalanceInsufficient: err2.ErrorWechatAccountBalanceInsufficient(ErrorWechatAccountBalanceInsufficient),
ErrorWechatBatchBudgetDepleted: err2.ErrorWechatBatchBudgetDepleted(ErrorWechatBatchBudgetDepleted),
ErrorWechatMerchantNoPermission: err2.ErrorWechatMerchantNoPermission(ErrorWechatMerchantNoPermission),
ErrorWechatCrossMerchantNotSupported: err2.ErrorWechatCrossMerchantNotSupported(ErrorWechatCrossMerchantNotSupported),
ErrorWechatUserReceiveLimit: err2.ErrorWechatUserReceiveLimit(ErrorWechatUserReceiveLimit),
ErrorWechatAPIChannelNotSupported: err2.ErrorWechatAPIChannelNotSupported(ErrorWechatAPIChannelNotSupported),
ErrorWechatSpecifiedDenominationNotSupported: err2.ErrorWechatSpecifiedDenominationNotSupported(ErrorWechatSpecifiedDenominationNotSupported),
ErrorWechatOnlyAdvertisingBatch: err2.ErrorWechatOnlyAdvertisingBatch(ErrorWechatOnlyAdvertisingBatch),
ErrorWechatUserMaxCoupons: err2.ErrorWechatUserMaxCoupons(ErrorWechatUserMaxCoupons),
ErrorWechatNaturalPersonRuleBlocked: err2.ErrorWechatNaturalPersonRuleBlocked(ErrorWechatNaturalPersonRuleBlocked),
ErrorWechatResourceNotExists: err2.ErrorWechatResourceNotExists(ErrorWechatResourceNotExists),
ErrorWechatFrequencyLimited: err2.ErrorWechatFrequencyLimited(ErrorWechatFrequencyLimited),
}
type ErrBody struct {
Code ErrCode `json:"Code"`
Message string `json:"Message"`
}
// GetWechatError 根据错误描述获取具体的错误处理
func (s ErrBody) GetWechatError() *errors.Error {
lowerDesc := strings.ToLower(s.Message)
for desc, err := range WechatError {
if strings.ToLower(desc) == lowerDesc {
return err
}
}
return err2.ErrorWechatFAIL(fmt.Sprintf("微信返回错误:%s", s.Message))
}