360 lines
14 KiB
Go
360 lines
14 KiB
Go
package businesserr
|
||
|
||
import (
|
||
"fmt"
|
||
"github.com/go-kratos/kratos/v2/errors"
|
||
"strings"
|
||
err2 "voucher/api/err"
|
||
)
|
||
|
||
// 定义错误码常量
|
||
// https://pay.weixin.qq.com/doc/v3/merchant/4012463767
|
||
const (
|
||
SYSTEM_ERROR ErrCode = "SYSTEM_ERROR"
|
||
SIGN_ERROR ErrCode = "SIGN_ERROR"
|
||
|
||
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"
|
||
)
|
||
|
||
const (
|
||
BATCH_NOT_STARTED ErrCode = "BATCH_NOT_STARTED"
|
||
BATCH_ENDED ErrCode = "BATCH_ENDED"
|
||
)
|
||
|
||
// CmbAPIErrorMap 定义错误映射,方便根据错误码获取错误信息
|
||
var CmbAPIErrorMap = map[ErrCode][]CmbAPIError{
|
||
|
||
SYSTEM_ERROR: {
|
||
{
|
||
StatusCode: 500,
|
||
ErrorCode: SYSTEM_ERROR,
|
||
Description: "系统异常,请稍后重试",
|
||
Hint: "请稍后重试",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
SIGN_ERROR: {
|
||
{
|
||
StatusCode: 401,
|
||
ErrorCode: SIGN_ERROR,
|
||
Description: "验证不通过",
|
||
Hint: "请参阅 签名常见问题",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
|
||
APPID_MCHID_NOT_MATCH: {
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: APPID_MCHID_NOT_MATCH,
|
||
Description: "商户号与AppID不匹配",
|
||
Hint: "调用接口的商户号需与接口传入的AppID有绑定关系,请参考常见问题Q4",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
INVALID_REQUEST: {
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "HTTP 请求不符合微信支付 APIv3 接口规则",
|
||
Hint: "请参阅 接口规则",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "OpenID与AppID不匹配",
|
||
Hint: "OpenID与AppID需有对应关系",
|
||
ThirdErrCode: ThirdErrCodeAppIDOpenIDMismatch,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "非法的商户号",
|
||
Hint: "请检查商户号准确性",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "调用频率过高",
|
||
Hint: "请降低API调用频率",
|
||
ThirdErrCode: ThirdErrCodeCallHigh,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "活动已结束或未激活",
|
||
Hint: "请检查批次状态",
|
||
ThirdErrCode: ThirdErrCodeBatchEnded, //前置判断时间处理一下
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: INVALID_REQUEST,
|
||
Description: "批次信息获取失败,请确认参数是否有误",
|
||
Hint: "请检查创建商户号与批次号的对应关系",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
PARAM_ERROR: {
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "参数错误",
|
||
Hint: "请根据错误提示正确传入参数",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "AppID必填",
|
||
Hint: "请输入AppID",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "OpenID必填",
|
||
Hint: "请输入OpenID",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "批次号必填",
|
||
Hint: "请输入批次号",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "商户号必填",
|
||
Hint: "请输入商户号",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 400,
|
||
ErrorCode: PARAM_ERROR,
|
||
Description: "非法的批次状态",
|
||
Hint: "请检查批次状态,仅支持发放状态为“运营中”的代金券批次",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
MCH_NOT_EXISTS: {
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: MCH_NOT_EXISTS,
|
||
Description: "商户号不合法",
|
||
Hint: "请检查商户号准确性",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
NOT_ENOUGH: {
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: NOT_ENOUGH,
|
||
Description: "批次预算不足",
|
||
Hint: "批次预算已发放完,请补充批次预算",
|
||
ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: NOT_ENOUGH,
|
||
Description: "发券超过单天限额",
|
||
Hint: "已超过该批次设置的单天发放限制额度,无法发放",
|
||
ThirdErrCode: ThirdErrCodeDailyLimit,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: NOT_ENOUGH,
|
||
Description: "账户余额不足,请充值",
|
||
Hint: "商户号余额不足,无法继续发券,请充值",
|
||
ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: NOT_ENOUGH,
|
||
Description: "批次预算耗尽",
|
||
Hint: "该批次的预算已经耗尽",
|
||
ThirdErrCode: ThirdErrCodeAdvanceFundingNotEnough,
|
||
},
|
||
},
|
||
REQUEST_BLOCKED: {
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "商户无权发券",
|
||
Hint: "该批次不支持其他商户发放,请参考常见问题Q1",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "批次不支持跨商户发券",
|
||
Hint: "该批次不支持其他商户发放,请参考常见问题Q1",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "用户被限领拦截",
|
||
Hint: "该用户已达到该批次的领取上限,请参考常见问题Q6",
|
||
ThirdErrCode: ThirdErrCodeUserParticipationExceeded,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "不能在API渠道发放",
|
||
Hint: "请检查批次信息,仅支持发放微信支付代金券,不支持发放立减与折扣",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "不支持指定面额发券",
|
||
Hint: "仅在发券时指定面额及门槛的场景才生效,常规发券场景请勿传入该信息",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: REQUEST_BLOCKED,
|
||
Description: "仅在广告场景下发放批次",
|
||
Hint: "该批次已在朋友圈广告发放,不支持在其他渠道发放",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
RULE_LIMIT: {
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: RULE_LIMIT,
|
||
Description: "用户已达最大领券次数",
|
||
Hint: "该用户已达到该批次的领取上限,请参考常见问题Q6",
|
||
ThirdErrCode: ThirdErrCodeUserParticipationExceeded,
|
||
},
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: RULE_LIMIT,
|
||
Description: "被自然人规则拦截",
|
||
Hint: "该自然人已达到该批次的领取上限,请参考常见问题Q6",
|
||
ThirdErrCode: ThirdErrCodeUserAccountAbnormal,
|
||
},
|
||
},
|
||
USER_ACCOUNT_ABNORMAL: {
|
||
{
|
||
StatusCode: 403,
|
||
ErrorCode: USER_ACCOUNT_ABNORMAL,
|
||
Description: "用户非法",
|
||
Hint: "用户命中微信支付风控模型,请参考常见问题Q5",
|
||
ThirdErrCode: ThirdErrCodeUserAccountFrozen,
|
||
},
|
||
},
|
||
RESOURCE_NOT_EXISTS: {
|
||
{
|
||
StatusCode: 404,
|
||
ErrorCode: RESOURCE_NOT_EXISTS,
|
||
Description: "批次不存在",
|
||
Hint: "请检查批次及制券商户号信息",
|
||
ThirdErrCode: ThirdErrCodeDefault,
|
||
},
|
||
},
|
||
FREQUENCY_LIMITED: {
|
||
{
|
||
StatusCode: 429,
|
||
ErrorCode: FREQUENCY_LIMITED,
|
||
Description: "当前请求人数过多,请稍后重试",
|
||
Hint: "请降低API调用频率",
|
||
ThirdErrCode: ThirdErrCodeCallHigh,
|
||
},
|
||
},
|
||
}
|
||
|
||
// 使用常量定义错误描述,减少硬编码
|
||
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 = "当前请求人数过多,请稍后重试"
|
||
ErrorWechatAccountFail = "该用户账号异常,无法领券。商家可联系微信支付或让用户联系微信支付客服处理。"
|
||
)
|
||
|
||
// 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),
|
||
ErrorWechatAccountFail: err2.ErrorWechatAccountFail(ErrorWechatAccountFail),
|
||
}
|
||
|
||
type WechatErrBody struct {
|
||
Code ErrCode `json:"Code"`
|
||
Message string `json:"Message"`
|
||
}
|
||
|
||
// GetWechatError 根据错误描述获取具体的错误处理
|
||
func (s WechatErrBody) 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))
|
||
}
|