新增代理实名认证和授权
This commit is contained in:
@@ -2,8 +2,11 @@ package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -11,6 +14,7 @@ import (
|
||||
"github.com/smartwalle/alipay/v3"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
@@ -95,9 +99,48 @@ func (l *AlipayCallbackLogic) handleQueryOrderPayment(w http.ResponseWriter, not
|
||||
}
|
||||
|
||||
if order.Status == "paid" {
|
||||
if asyncErr := l.svcCtx.AsynqService.SendQueryTask(order.Id); asyncErr != nil {
|
||||
logx.Errorf("异步任务调度失败: %v", asyncErr)
|
||||
return asyncErr
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return fmt.Errorf("解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return fmt.Errorf("解析参数失败: %+v", err)
|
||||
}
|
||||
encryptName, err := crypto.AesEncrypt([]byte(paramsMap["name"]), key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("生成订单, 加密姓名失败: %+v", err)
|
||||
}
|
||||
encryptIdcard, err := crypto.AesEncrypt([]byte(paramsMap["id_card"]), key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("生成订单, 加密身份证号失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: order.Id,
|
||||
UserId: order.UserId,
|
||||
TargetName: encryptName,
|
||||
TargetIdcard: encryptIdcard,
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return fmt.Errorf("插入授权信息失败: %+v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +226,7 @@ func (l *AlipayCallbackLogic) handleAgentVipOrderPayment(w http.ResponseWriter,
|
||||
return nil
|
||||
}
|
||||
|
||||
// 退款
|
||||
func (l *AlipayCallbackLogic) handleRefund(order *model.AgentMembershipRechargeOrder) error {
|
||||
ctx := context.Background()
|
||||
// 退款
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
@@ -125,6 +126,14 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
amount = 0.01
|
||||
}
|
||||
var orderID int64
|
||||
Status := "pending"
|
||||
env := os.Getenv("ENV")
|
||||
if env == "" {
|
||||
env = "production"
|
||||
}
|
||||
if env == "development" {
|
||||
Status = "paid"
|
||||
}
|
||||
order := model.Order{
|
||||
OrderNo: outTradeNo,
|
||||
UserId: userID,
|
||||
@@ -132,7 +141,7 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
PaymentPlatform: req.PayMethod,
|
||||
PaymentScene: "app",
|
||||
Amount: amount,
|
||||
Status: "pending",
|
||||
Status: Status,
|
||||
}
|
||||
orderInsertResult, insertOrderErr := l.svcCtx.OrderModel.Insert(l.ctx, session, &order)
|
||||
if insertOrderErr != nil {
|
||||
@@ -157,6 +166,53 @@ func (l *PaymentLogic) QueryOrderPayment(req *types.PaymentReq, session sqlx.Ses
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "生成订单, 保存代理订单失败: %+v", agentOrderInsert)
|
||||
}
|
||||
}
|
||||
|
||||
if env == "development" {
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err = json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 解析参数失败: %+v", err)
|
||||
}
|
||||
|
||||
encryptName, err := crypto.AesEncrypt([]byte(paramsMap["name"]), key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 加密姓名失败: %+v", err)
|
||||
}
|
||||
encryptIdcard, err := crypto.AesEncrypt([]byte(paramsMap["id_card"]), key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 加密身份证号失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: orderID,
|
||||
UserId: order.UserId,
|
||||
TargetName: encryptName,
|
||||
TargetIdcard: encryptIdcard,
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 插入授权信息失败: %+v", err)
|
||||
}
|
||||
}
|
||||
return &PaymentTypeResp{amount: amount, outTradeNo: outTradeNo, description: product.ProductName}, nil
|
||||
}
|
||||
func (l *PaymentLogic) AgentVipOrderPayment(req *types.PaymentReq, session sqlx.Session) (resp *PaymentTypeResp, err error) {
|
||||
|
||||
100
app/user/cmd/api/internal/logic/pay/querypaymentchecklogic.go
Normal file
100
app/user/cmd/api/internal/logic/pay/querypaymentchecklogic.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"qnc-server/app/user/cmd/api/internal/svc"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/common/xerr"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type QueryPaymentCheckLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewQueryPaymentCheckLogic(ctx context.Context, svcCtx *svc.ServiceContext) *QueryPaymentCheckLogic {
|
||||
return &QueryPaymentCheckLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *QueryPaymentCheckLogic) QueryPaymentCheck(req *types.QueryPaymentCheckReq) (resp *types.QueryPaymentCheckResp, err error) {
|
||||
order, err := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询订单失败: %v", err)
|
||||
}
|
||||
product, err := l.svcCtx.ProductModel.FindOne(l.ctx, order.ProductId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询产品失败: %v", err)
|
||||
}
|
||||
resp = new(types.QueryPaymentCheckResp)
|
||||
resp.OrderStatus = order.Status
|
||||
resp.ProductName = product.ProductName
|
||||
|
||||
if order.Status == "paid" {
|
||||
authorization, err := l.svcCtx.AuthorizationModel.FindOneByOrderId(l.ctx, order.Id)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询授权信息失败: %v", err)
|
||||
}
|
||||
resp.AuthorizationStatus = authorization.Status
|
||||
key, decodeErr := hex.DecodeString(l.svcCtx.Config.Encrypt.SecretKey)
|
||||
if decodeErr != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", decodeErr)
|
||||
}
|
||||
decryptName, err := crypto.AesDecrypt(authorization.TargetName, key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", err)
|
||||
}
|
||||
idCard, err := crypto.AesDecrypt(authorization.TargetIdcard, key)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询授权信息失败: %v", err)
|
||||
}
|
||||
resp.Name = maskName(string(decryptName))
|
||||
resp.IdCard = maskIDCard(string(idCard))
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// 姓名脱敏
|
||||
func maskName(name string) string {
|
||||
// 将字符串转换为rune切片以正确处理中文字符
|
||||
runes := []rune(name)
|
||||
length := len(runes)
|
||||
|
||||
if length <= 1 {
|
||||
return name
|
||||
}
|
||||
|
||||
if length == 2 {
|
||||
// 两个字:保留第一个字,第二个字用*替代
|
||||
return string(runes[0]) + "*"
|
||||
}
|
||||
|
||||
// 三个字及以上:保留首尾字,中间用*替代
|
||||
first := string(runes[0])
|
||||
last := string(runes[length-1])
|
||||
mask := strings.Repeat("*", length-2)
|
||||
|
||||
return first + mask + last
|
||||
}
|
||||
|
||||
// 身份证号脱敏
|
||||
func maskIDCard(idCard string) string {
|
||||
length := len(idCard)
|
||||
if length <= 10 {
|
||||
return idCard // 如果长度太短,可能不是身份证,不处理
|
||||
}
|
||||
// 保留前3位和后4位
|
||||
return idCard[:3] + strings.Repeat("*", length-7) + idCard[length-4:]
|
||||
}
|
||||
@@ -2,10 +2,14 @@ package pay
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"qnc-server/app/user/cmd/api/internal/service"
|
||||
"qnc-server/app/user/cmd/api/internal/types"
|
||||
"qnc-server/app/user/model"
|
||||
"qnc-server/pkg/lzkit/crypto"
|
||||
"qnc-server/pkg/lzkit/lzUtils"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -197,15 +201,41 @@ func (l *WechatPayCallbackLogic) handleRefund(order *model.AgentMembershipRechar
|
||||
return refundErr
|
||||
}
|
||||
if refund.IsSuccess() {
|
||||
logx.Errorf("支付宝退款成功, orderID: %d", order.Id)
|
||||
// 更新订单状态为退款
|
||||
order.Status = "refunded"
|
||||
updateOrderErr := l.svcCtx.AgentMembershipRechargeOrderModel.UpdateWithVersion(ctx, nil, order)
|
||||
if updateOrderErr != nil {
|
||||
logx.Errorf("更新订单状态失败,订单ID: %d, 错误: %v", order.Id, updateOrderErr)
|
||||
return fmt.Errorf("更新订单状态失败: %v", updateOrderErr)
|
||||
redisKey := fmt.Sprintf(types.QueryCacheKey, order.UserId, order.OrderNo)
|
||||
cache, cacheErr := l.svcCtx.Redis.Get(redisKey)
|
||||
if cacheErr != nil {
|
||||
return fmt.Errorf("获取缓存内容失败: %+v", cacheErr)
|
||||
}
|
||||
var data types.QueryCacheLoad
|
||||
err := json.Unmarshal([]byte(cache), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("解析缓存内容失败: %+v", err)
|
||||
}
|
||||
secretKey := l.svcCtx.Config.Encrypt.SecretKey
|
||||
key, decodeErr := hex.DecodeString(secretKey)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("获取AES密钥失败: %+v", decodeErr)
|
||||
}
|
||||
decryptData, aesdecryptErr := crypto.AesDecrypt(data.Params, key)
|
||||
if aesdecryptErr != nil {
|
||||
return fmt.Errorf("解密参数失败: %+v", aesdecryptErr)
|
||||
}
|
||||
var paramsMap map[string]string
|
||||
if err := json.Unmarshal([]byte(decryptData), ¶msMap); err != nil {
|
||||
return fmt.Errorf("解析参数失败: %+v", err)
|
||||
}
|
||||
_, err = l.svcCtx.AuthorizationModel.Insert(l.ctx, nil, &model.Authorization{
|
||||
OrderId: order.Id,
|
||||
UserId: order.UserId,
|
||||
TargetName: paramsMap["name"],
|
||||
TargetIdcard: paramsMap["id_card"],
|
||||
GrantType: model.GrantTypeFace,
|
||||
Status: model.AuthorizationStatusPending,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorf("支付宝支付回调,插入授权信息失败: %+v", err)
|
||||
return fmt.Errorf("插入授权信息失败: %+v", err)
|
||||
}
|
||||
return nil
|
||||
} else {
|
||||
logx.Errorf("支付宝退款失败:%v", refundErr)
|
||||
return refundErr
|
||||
|
||||
Reference in New Issue
Block a user