cmb
This commit is contained in:
parent
7c764e53b7
commit
84f53cc4fc
|
|
@ -0,0 +1,143 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package api.v1;
|
||||
option go_package = "voucher/api/v1;v1";
|
||||
|
||||
import "validate/validate.proto";
|
||||
|
||||
|
||||
message CmbOrderRequest {
|
||||
// 公共参数
|
||||
// 合作方唯一ID,32位定长
|
||||
string mid = 1 [json_name = "mid"];
|
||||
// 应用唯一ID,32位定长
|
||||
string aid = 2 [json_name = "aid"];
|
||||
// 时间戳 yyyyMMddHHmmss
|
||||
string date = 3 [json_name = "date"];
|
||||
// 随机字符串,保证签名不可预测,不长于32位
|
||||
string random = 4 [json_name = "random"];
|
||||
// 合作方密钥对别名
|
||||
string keyAlias = 5 [json_name = "keyAlias"];
|
||||
// 掌上生活密钥对别名
|
||||
string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"];
|
||||
// 加密报文,是否需要加密,请查看各API的说明文档
|
||||
string encryptBody = 7 [json_name = "encryptBody"];
|
||||
// 签名,具体详见签名规范
|
||||
string sign = 8 [json_name = "sign"];
|
||||
|
||||
// 业务参数
|
||||
// 唯一流水号,需支持14天内幂等
|
||||
string transactionId = 9 [json_name = "transactionId", (validate.rules).string = {min_len: 1,max_len: 50}];
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 10 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
|
||||
// 招商银行用户号 用户标识,比如手机号、支付宝openId
|
||||
string cmbUid = 11 [json_name = "cmbUid", (validate.rules).string = {min_len: 1,max_len: 100}];
|
||||
// 用户标识类型,0-手机号,1-支付宝openId
|
||||
string cmbUidType = 12 [json_name = "cmbUidType", (validate.rules).string = {min_len: 1,max_len: 10}];
|
||||
// 时间戳,长度为13位,精度为毫秒
|
||||
string timestamp = 13 [json_name = "timestamp", (validate.rules).string = {min_len: 1,max_len: 20}];
|
||||
}
|
||||
message CmbOrderReply {
|
||||
// 公共参数
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回话术,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
// 时间戳 yyyyMMddHHmmss
|
||||
string date = 3 [json_name = "date"];
|
||||
// 合作方密钥对别名
|
||||
string keyAlias = 5 [json_name = "keyAlias"];
|
||||
// 掌上生活密钥对别名
|
||||
string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"];
|
||||
// 加密报文,是否需要加密,请查看各API的说明文档
|
||||
string encryptBody = 7 [json_name = "encryptBody"];
|
||||
// 签名,具体详见签名规范
|
||||
string sign = 8 [json_name = "sign"];
|
||||
|
||||
// 业务参数
|
||||
// 权益标识,优惠券券码,最大长度为50位
|
||||
string codeNo = 9 [json_name = "codeNo"];
|
||||
}
|
||||
|
||||
|
||||
message CmbQueryProductRequest {
|
||||
// 公共参数
|
||||
// 合作方唯一ID,32位定长
|
||||
string mid = 1 [json_name = "mid"];
|
||||
// 应用唯一ID,32位定长
|
||||
string aid = 2 [json_name = "aid"];
|
||||
// 时间戳 yyyyMMddHHmmss
|
||||
string date = 3 [json_name = "date"];
|
||||
// 随机字符串,保证签名不可预测,不长于32位
|
||||
string random = 4 [json_name = "random"];
|
||||
// 合作方密钥对别名
|
||||
string keyAlias = 5 [json_name = "keyAlias"];
|
||||
// 掌上生活密钥对别名
|
||||
string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"];
|
||||
// 加密报文,是否需要加密,请查看各API的说明文档
|
||||
string encryptBody = 7 [json_name = "encryptBody"];
|
||||
// 签名,具体详见签名规范
|
||||
string sign = 8 [json_name = "sign"];
|
||||
|
||||
// 业务参数
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 9 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
|
||||
}
|
||||
message CmbQueryProductReply {
|
||||
// 公共参数
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回话术,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
// 时间戳 yyyyMMddHHmmss
|
||||
string date = 3 [json_name = "date"];
|
||||
// 合作方密钥对别名
|
||||
string keyAlias = 5 [json_name = "keyAlias"];
|
||||
// 掌上生活密钥对别名
|
||||
string cmbKeyAlias = 6 [json_name = "cmbKeyAlias"];
|
||||
// 加密报文,是否需要加密,请查看各API的说明文档
|
||||
string encryptBody = 7 [json_name = "encryptBody"];
|
||||
// 签名,具体详见签名规范
|
||||
string sign = 8 [json_name = "sign"];
|
||||
|
||||
// 业务参数
|
||||
// 批次名称
|
||||
string activityName = 9 [json_name = "activityName"];
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 10 [json_name = "activityId"];
|
||||
// 批次额度 单位为分
|
||||
string amount = 11 [json_name = "amount"];
|
||||
// 门槛,单位为分
|
||||
string minAmount = 12 [json_name = "minAmount"];
|
||||
// 有效期形式,0:固定有效期,1:动态有效期
|
||||
string availableType = 13 [json_name = "availableType"];
|
||||
// 动态有效期天数-非必填 格式yyyy-mm-dd hh:mm:ss.sss
|
||||
string availableDays = 14 [json_name = "availableDays"];
|
||||
// 有效期开始时间-非必填
|
||||
string startTime = 15 [json_name = "startTime"];
|
||||
// 有效期结束时间-非必填
|
||||
string endTime = 16 [json_name = "endTime"];
|
||||
// 当前可用库存
|
||||
string availableStock = 17 [json_name = "availableStock"];
|
||||
// 细则描述
|
||||
string detail = 18 [json_name = "detail"];
|
||||
}
|
||||
|
||||
message CmbNotifyRequest {
|
||||
// 优惠券券码,codeNo
|
||||
string ticket = 1 [json_name = "ticket"];
|
||||
// 更新后串码状态,0:可使用,1:已使用
|
||||
string status = 2 [json_name = "status"];
|
||||
// 验码日期,格式yyyy-mm-dd hh:mm:ss.sss
|
||||
string transDate = 3 [json_name = "transDate"];
|
||||
// 发码机构号,固定值,掌上生活优惠券系统提供
|
||||
string orgNo = 4 [json_name = "orgNo"];
|
||||
// 扩展字段
|
||||
string ext = 5 [json_name = "ext"];
|
||||
}
|
||||
message CmbNotifyReply {
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回信息,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package api.v1;
|
||||
option go_package = "voucher/api/v1;v1";
|
||||
|
||||
import "validate/validate.proto";
|
||||
|
||||
|
||||
message CmbOrderRequest {
|
||||
// 唯一流水号,需支持14天内幂等
|
||||
string transactionId = 1 [json_name = "transactionId", (validate.rules).string = {min_len: 1,max_len: 50}];
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 2 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
|
||||
// 招商银行用户号 用户标识,比如手机号、支付宝openId
|
||||
string cmbUid = 3 [json_name = "cmbUid", (validate.rules).string = {min_len: 1,max_len: 100}];
|
||||
// 用户标识类型,0-手机号,1-支付宝openId
|
||||
string cmbUidType = 4 [json_name = "cmbUidType", (validate.rules).string = {min_len: 1,max_len: 10}];
|
||||
// 时间戳,长度为13位,精度为毫秒
|
||||
string timestamp = 5 [json_name = "timestamp", (validate.rules).string = {min_len: 1,max_len: 20}];
|
||||
}
|
||||
message CmbOrderReply {
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回信息,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
// 权益标识,优惠券券码,最大长度为50位
|
||||
string codeNo = 3 [json_name = "codeNo"];
|
||||
}
|
||||
|
||||
|
||||
message CmbQueryProductRequest {
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 2 [json_name = "activityId", (validate.rules).string = {min_len: 1,max_len: 32}];
|
||||
}
|
||||
message CmbQueryProductReply {
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回信息,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
// 批次名称
|
||||
string activityName = 3 [json_name = "activityName"];
|
||||
// 外部合作方权益批次号
|
||||
string activityId = 4 [json_name = "activityId"];
|
||||
// 批次额度 单位为分
|
||||
string amount = 5 [json_name = "amount"];
|
||||
// 门槛,单位为分
|
||||
string minAmount = 6 [json_name = "minAmount"];
|
||||
// 有效期形式,0:固定有效期,1:动态有效期
|
||||
string availableType = 7 [json_name = "availableType"];
|
||||
// 动态有效期天数-非必填 格式yyyy-mm-dd hh:mm:ss.sss
|
||||
string availableDays = 8 [json_name = "availableDays"];
|
||||
// 有效期开始时间-非必填
|
||||
string startTime = 9 [json_name = "startTime"];
|
||||
// 有效期结束时间-非必填
|
||||
string endTime = 10 [json_name = "endTime"];
|
||||
// 当前可用库存
|
||||
string availableStock = 11 [json_name = "availableStock"];
|
||||
// 细则描述
|
||||
string detail = 12 [json_name = "detail"];
|
||||
}
|
||||
|
||||
message CmbNotifyRequest {
|
||||
// 优惠券券码,codeNo
|
||||
string ticket = 1 [json_name = "ticket"];
|
||||
// 更新后串码状态,0:可使用,1:已使用
|
||||
string status = 2 [json_name = "status"];
|
||||
// 验码日期,格式yyyy-mm-dd hh:mm:ss.sss
|
||||
string transDate = 3 [json_name = "transDate"];
|
||||
// 发码机构号,固定值,掌上生活优惠券系统提供
|
||||
string orgNo = 4 [json_name = "orgNo"];
|
||||
// 扩展字段
|
||||
string ext = 5 [json_name = "ext"];
|
||||
}
|
||||
message CmbNotifyReply {
|
||||
// 接口调用返回码,1000 成功,1001 失败
|
||||
string respCode = 1 [json_name = "respCode"];
|
||||
// 返回信息,失败信息落此字段
|
||||
string respMsg = 2 [json_name = "respMsg"];
|
||||
}
|
||||
|
|
@ -52,6 +52,10 @@ wechat:
|
|||
mchID: "1605446142" # 证书所属商户
|
||||
mchCertificateSerialNumber: "4D081089DEB385316CBDCB55C070287E4920AC76"
|
||||
|
||||
cmb:
|
||||
mid: "d6fdd78b6fd13a808818286b9cad9687"
|
||||
aid: "5efaa21263b94f669a1c90ed0279df20"
|
||||
|
||||
#配置日志
|
||||
logs:
|
||||
business: business.log #业务日志路径:如果不写日志,则不配置或配置为空
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ type OrderBo struct {
|
|||
OutBizNo string
|
||||
ProductNo string
|
||||
Account string
|
||||
Type vo.OrderType
|
||||
AccountType vo.OrderAccountType
|
||||
Status vo.OrderStatus
|
||||
AppID string
|
||||
|
|
@ -22,14 +23,10 @@ type OrderBo struct {
|
|||
}
|
||||
|
||||
type OrderCreateReqBo struct {
|
||||
OrderNo string
|
||||
OutBizNo string
|
||||
ProductNo string
|
||||
Account string
|
||||
AccountType vo.OrderAccountType
|
||||
Channel vo.Channel
|
||||
AppID string
|
||||
MerchantNo string
|
||||
}
|
||||
|
||||
type OrderCreateRepBo struct {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"gorm.io/gorm"
|
||||
"time"
|
||||
"voucher/internal/biz/bo"
|
||||
"voucher/internal/biz/vo"
|
||||
"voucher/internal/pkg/lock"
|
||||
"voucher/internal/pkg/uid"
|
||||
)
|
||||
|
|
@ -25,13 +26,36 @@ func (v *VoucherBiz) CmbOrder(ctx context.Context, req *bo.OrderCreateReqBo) (re
|
|||
return nil
|
||||
}
|
||||
|
||||
product, err := v.ProductRepo.GetByPNO(ctx, req.ProductNo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
orderNo, err := v.GenerateMixRepo.GeneratorString(ctx, uid.Order)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
req.OrderNo = orderNo
|
||||
v.OrderRepo.Create(ctx, req)
|
||||
o := &bo.OrderBo{
|
||||
OrderNo: orderNo,
|
||||
|
||||
OutBizNo: req.OutBizNo,
|
||||
ProductNo: req.ProductNo,
|
||||
Account: req.Account,
|
||||
|
||||
AppID: product.AppID,
|
||||
MerchantNo: product.MerchantNo,
|
||||
Channel: product.Channel,
|
||||
|
||||
AccountType: vo.OrderAccountTypeOpenId,
|
||||
Type: vo.OrderTypeCmb,
|
||||
Status: vo.OrderStatusWait,
|
||||
}
|
||||
|
||||
order, err = v.OrderRepo.Create(ctx, o)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
package cmb
|
||||
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
type OrderRepo interface {
|
||||
GetByOutBizNo(ctx context.Context, outBizNo string) (*bo.OrderBo, error)
|
||||
Create(ctx context.Context, req *bo.OrderCreateReqBo) (*bo.OrderBo, error)
|
||||
Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderBo, error)
|
||||
GetByID(ctx context.Context, id uint64) (*bo.OrderBo, error)
|
||||
Ing(ctx context.Context, id uint64) error
|
||||
Success(ctx context.Context, id uint64) error
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package vo
|
||||
|
||||
type OrderType uint8
|
||||
|
||||
const (
|
||||
OrderTypeCmb OrderType = iota + 1
|
||||
)
|
||||
|
||||
var OrderTypeMap = map[OrderType]string{
|
||||
OrderTypeCmb: "招行",
|
||||
}
|
||||
|
||||
func (s OrderType) GetText() string {
|
||||
if t, ok := OrderTypeMap[s]; ok {
|
||||
return t
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s OrderType) GetValue() uint8 {
|
||||
return uint8(s)
|
||||
}
|
||||
|
||||
func (s OrderType) IsCmb() bool {
|
||||
return s == OrderTypeCmb
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import (
|
|||
type VoucherBiz struct {
|
||||
rdb *data.Rdb
|
||||
OrderRepo repo.OrderRepo
|
||||
ProductRepo repo.ProductRepo
|
||||
ThirdMQSend thirdrepo.ThirdMQSend
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo
|
||||
GenerateMixRepo mixrepos.GenerateMixRepo
|
||||
|
|
@ -19,6 +20,7 @@ type VoucherBiz struct {
|
|||
func NewVoucherBiz(
|
||||
rdb *data.Rdb,
|
||||
orderRepo repo.OrderRepo,
|
||||
ProductRepo repo.ProductRepo,
|
||||
thirdMQSend thirdrepo.ThirdMQSend,
|
||||
WechatCpnRepo wechatrepo.WechatCpnRepo,
|
||||
GenerateMixRepo mixrepos.GenerateMixRepo,
|
||||
|
|
@ -26,6 +28,7 @@ func NewVoucherBiz(
|
|||
return &VoucherBiz{
|
||||
rdb: rdb,
|
||||
OrderRepo: orderRepo,
|
||||
ProductRepo: ProductRepo,
|
||||
ThirdMQSend: thirdMQSend,
|
||||
WechatCpnRepo: WechatCpnRepo,
|
||||
GenerateMixRepo: GenerateMixRepo,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ type Order struct {
|
|||
ProductNo string `gorm:"column:product_no;not null;comment:商品编号" json:"product_no"` // 商品编号
|
||||
Account string `gorm:"column:account;not null;comment:充值账号" json:"account"` // 充值账号
|
||||
AccountType uint8 `gorm:"column:account_type;not null;comment:1:oepnid/userid 2:手机号" json:"account_type"` // 1:oepnid/userid 2:手机号
|
||||
Type uint8 `gorm:"column:type;not null;comment:1:招行" json:"type"`
|
||||
Status uint8 `gorm:"column:status;not null;comment:1:待发放 2:发放中 3:发放成功 4:发放失败" json:"status"` // 1:待发放 2:发放中 3:发放成功 4:发放失败
|
||||
AppID string `gorm:"column:app_id;not null;comment:批次所属应用" json:"app_id"` // 批次所属应用
|
||||
MerchantNo string `gorm:"column:merchant_no;not null;comment:创建批次号的商户号" json:"merchant_no"` // 创建批次号的商户号
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ func (p *OrderRepoImpl) DB(ctx context.Context) *gorm.DB {
|
|||
return p.db.DB(ctx).Model(model.Order{})
|
||||
}
|
||||
|
||||
func (p *OrderRepoImpl) Create(ctx context.Context, req *bo.OrderCreateReqBo) (*bo.OrderBo, error) {
|
||||
func (p *OrderRepoImpl) Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderBo, error) {
|
||||
now := time.Now()
|
||||
|
||||
info := &model.Order{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ func (s *VoucherService) CmbOrder(ctx http.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := req.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// todo 签名验证
|
||||
|
||||
boReq := &bo.OrderCreateReqBo{
|
||||
|
|
@ -21,7 +25,6 @@ func (s *VoucherService) CmbOrder(ctx http.Context) error {
|
|||
ProductNo: req.ActivityId,
|
||||
Account: req.CmbUid,
|
||||
AccountType: vo.OrderAccountTypeOpenId,
|
||||
Channel: vo.OrderChannelWechat,
|
||||
}
|
||||
|
||||
boRep, err := s.VoucherBiz.CmbOrder(ctx, boReq)
|
||||
|
|
@ -45,6 +48,10 @@ func (s *VoucherService) CmbProductQuery(ctx http.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := req.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rep := &v1.CmbQueryProductReply{}
|
||||
|
||||
return ctx.JSON(200, rep)
|
||||
|
|
|
|||
Loading…
Reference in New Issue