You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
219 lines
5.7 KiB
219 lines
5.7 KiB
package realname |
|
|
|
import ( |
|
"context" |
|
"encoding/json" |
|
"fmt" |
|
"math/rand" |
|
"net/url" |
|
"regexp" |
|
"time" |
|
|
|
"go-common/app/interface/main/account/conf" |
|
"go-common/app/interface/main/account/model" |
|
memmodel "go-common/app/service/main/member/model" |
|
"go-common/library/ecode" |
|
"go-common/library/log" |
|
|
|
"github.com/pkg/errors" |
|
) |
|
|
|
var ( |
|
_idCard18Regexp = regexp.MustCompile(`^\d{17}[\d|x]$`) |
|
_idCard15Regexp = regexp.MustCompile(`^\d{15}$`) |
|
) |
|
|
|
// AlipayApply 提交芝麻认证申请 |
|
func (s *Service) AlipayApply(c context.Context, mid int64, param *model.ParamRealnameAlipayApply) (res *model.RealnameAlipayApply, err error) { |
|
if !s.alipayAntispamCheck(c, mid) { |
|
err = ecode.RealnameAlipayAntispam |
|
return |
|
} |
|
if !s.checkID(param.CardNum) { |
|
err = ecode.RealnameCardNumErr |
|
return |
|
} |
|
var bizno string |
|
if bizno, err = s.alipayInit(c, param.Realname, param.CardNum); err != nil { |
|
return |
|
} |
|
res = &model.RealnameAlipayApply{} |
|
if res.URL, err = s.alipayCertifyURL(c, bizno); err != nil { |
|
return |
|
} |
|
var ( |
|
arg = &memmodel.ArgRealnameAlipayApply{ |
|
MID: mid, |
|
CaptureCode: param.Capture, |
|
Realname: param.Realname, |
|
CardCode: param.CardNum, |
|
IMGToken: param.ImgToken, |
|
Bizno: bizno, |
|
} |
|
) |
|
if err = s.memRPC.RealnameAlipayApply(c, arg); err != nil { |
|
res = nil |
|
return |
|
} |
|
s.addmiss(func() { |
|
if missErr := s.alipayAntispamIncrease(context.Background(), mid); missErr != nil { |
|
log.Error("%+v", err) |
|
} |
|
}) |
|
return |
|
} |
|
|
|
func (s *Service) checkID(card string) bool { |
|
if !_idCard15Regexp.MatchString(card) && !_idCard18Regexp.MatchString(card) { |
|
return false |
|
} |
|
return true |
|
} |
|
|
|
func (s *Service) alipayInit(c context.Context, realname, cardNum string) (bizno string, err error) { |
|
var ( |
|
biz struct { |
|
TransID string `json:"transaction_id"` |
|
ProdCode string `json:"product_code"` |
|
BizCode string `json:"biz_code"` |
|
IdenParam struct { |
|
IdentityType string `json:"identity_type"` |
|
CertType string `json:"cert_type"` |
|
CertName string `json:"cert_name"` |
|
CertNo string `json:"cert_no"` |
|
} `json:"identity_param"` |
|
} |
|
param url.Values |
|
) |
|
biz.TransID = s.alipayTransactionID() // 商户请求的唯一标志,32位长度的字母数字下划线组合。该标识作为对账的关键信息,商户要保证其唯一性. |
|
biz.ProdCode = "w1010100000000002978" // 芝麻认证产品码 |
|
biz.BizCode = "FACE" // 认证场景码,支持的场景码有: FACE:多因子活体人脸认证, SMART_FACE:多因子快捷活体人脸认证, FACE_SDK:SDK活体人脸认证 签约的协议决定了可以使用的场景 |
|
biz.IdenParam.IdentityType = "CERT_INFO" |
|
biz.IdenParam.CertType = "IDENTITY_CARD" |
|
biz.IdenParam.CertName = realname |
|
biz.IdenParam.CertNo = cardNum |
|
if param, err = s.alipayParam("zhima.customer.certification.initialize", biz, ""); err != nil { |
|
return |
|
} |
|
if bizno, err = s.realnameDao.AlipayInit(c, param); err != nil { |
|
log.Error("%+v", err) |
|
err = ecode.RealnameAlipayErr |
|
return |
|
} |
|
if bizno == "" { |
|
err = ecode.RealnameAlipayErr |
|
return |
|
} |
|
return |
|
} |
|
|
|
func (s *Service) alipayCertifyURL(c context.Context, bizno string) (u string, err error) { |
|
var ( |
|
param url.Values |
|
biz struct { |
|
Bizno string `json:"biz_no"` |
|
} |
|
) |
|
biz.Bizno = bizno |
|
if param, err = s.alipayParam("zhima.customer.certification.certify", biz, "bilibili://auth.zhima"); err != nil { |
|
return |
|
} |
|
u = conf.Conf.Realname.Alipay.Gateway + "?" + param.Encode() |
|
return |
|
} |
|
|
|
// AlipayConfirm 查询芝麻认证状态 |
|
func (s *Service) AlipayConfirm(c context.Context, mid int64) (res *model.RealnameAlipayConfirm, err error) { |
|
var ( |
|
pass bool |
|
reason string |
|
rpcarg = &memmodel.ArgMemberMid{ |
|
Mid: mid, |
|
} |
|
rpcres *memmodel.RealnameAlipayInfo |
|
) |
|
if rpcres, err = s.memRPC.RealnameAlipayBizno(c, rpcarg); err != nil { |
|
return |
|
} |
|
if pass, reason, err = s.alipayQuery(c, rpcres.Bizno); err != nil { |
|
log.Error("%+v", err) |
|
err = ecode.RealnameAlipayErr |
|
return |
|
} |
|
res = &model.RealnameAlipayConfirm{ |
|
Reason: reason, |
|
} |
|
if pass { |
|
res.Passed = model.RealnameTrue |
|
} else { |
|
res.Passed = model.RealnameFalse |
|
} |
|
// rpc call |
|
var ( |
|
rpcConfirmArg = &memmodel.ArgRealnameAlipayConfirm{ |
|
MID: mid, |
|
Pass: pass, |
|
Reason: reason, |
|
} |
|
) |
|
if err = s.memRPC.RealnameAlipayConfirm(c, rpcConfirmArg); err != nil { |
|
return |
|
} |
|
s.addmiss(func() { |
|
if missErr := s.setAlipayAntispamPassFlag(context.Background(), mid, false); missErr != nil { |
|
log.Error("%+v", err) |
|
} |
|
}) |
|
return |
|
} |
|
|
|
func (s *Service) alipayQuery(c context.Context, bizno string) (pass bool, reason string, err error) { |
|
var ( |
|
param url.Values |
|
biz struct { |
|
Bizno string `json:"biz_no"` |
|
} |
|
) |
|
biz.Bizno = bizno |
|
if param, err = s.alipayParam("zhima.customer.certification.query", biz, ""); err != nil { |
|
return |
|
} |
|
if pass, reason, err = s.realnameDao.AlipayQuery(c, param); err != nil { |
|
log.Error("%+v", err) |
|
err = ecode.RealnameAlipayErr |
|
return |
|
} |
|
return |
|
} |
|
|
|
// alipayParam 构造阿里请求param,biz为 biz_content struct |
|
func (s *Service) alipayParam(method string, biz interface{}, returnURL string) (p url.Values, err error) { |
|
var ( |
|
sign string |
|
bizBytes []byte |
|
) |
|
if bizBytes, err = json.Marshal(biz); err != nil { |
|
err = errors.WithStack(err) |
|
return |
|
} |
|
p = url.Values{} |
|
p.Set("app_id", conf.Conf.Realname.Alipay.AppID) |
|
p.Set("method", method) |
|
p.Set("charset", "utf-8") |
|
p.Set("sign_type", "RSA2") |
|
p.Set("timestamp", time.Now().Format("2006-01-02 15:04:05")) |
|
p.Set("version", "1.0") |
|
p.Set("biz_content", string(bizBytes)) |
|
if returnURL != "" { |
|
p.Set("return_url", returnURL) |
|
} |
|
if sign, err = s.alipayCryptor.SignParam(p); err != nil { |
|
return |
|
} |
|
p.Set("sign", sign) |
|
return |
|
} |
|
|
|
func (s *Service) alipayTransactionID() string { |
|
return fmt.Sprintf("BILI%d%d", time.Now().UnixNano(), rand.Intn(100000)) |
|
}
|
|
|