Files
servicebase/pkg/partner/ZhimaCertify/ZhimaCertifyClient.go
2025-11-19 10:23:05 +08:00

214 lines
7.0 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 ZhimaCertify
import (
"encoding/json"
"errors"
"net/url"
"gitea.ddegame.cn/open/servicebase/pkg/htools"
"github.com/anxpp/beego/logs"
)
// 芝麻认证SDK
type ZhimaCertifyClient struct {
GatewayUrl string
AppId string
PublicKey string
PrivateKey string
}
// 芝麻开放平台的key
const (
// 蚂蚁开放平台 https://openapi.alipay.com/gateway.do
// 芝麻信用api https://zmopenapi.zmxy.com.cn/openapi.do
ZHIMA_MERCHANT_ID = "268282100002002118952271"
ZHIMA_CERTIFY_GATEWAY_URL = "https://zmopenapi.zmxy.com.cn/openapi.do" // 网关
ZHIMA_CERTIFY_APP_ID = "30000229371" // APPID
// 芝麻公钥
ZHIMA_CERTIFY_PUBLIC_KEY = `
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQK22BgQCNunjjn51b3XUnsTXGa6C3dBnA
U7UP1FCxJN4T1CIxCC5I+Fi9lrzFy899g224JzcTywePp3jIg4aG/11qIJS2edkTUo
7XM8qxpl+ApaRoCLx4NezDzOxVSGYqnu2295wnKW/ft3T+aZQwgELw60IrVutFMOKr1
H7yrrzbar/OrgaOxLQIDAQAB
-----END PUBLIC KEY-----
`
// 商户私钥
ZHIMA_CERTIFY_PRIVATE_KEY = `
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDHbe15atuwmQaIUiX9kx45T22dRDmfYz7+rIoQCjR3+J2AQkMX1g3
9BQZfRJyN8/31GD98zjZr0KowxFYnDJC422w+6mnAtY63fJW32VvIqTbz7PHF/iyVE0
WCWu2IlukzljaZFg6SK2SD5+ROQEYL3dhzg87/4iDvDIBKuK222HftTMPvLcwIDAQAB
AoGAREH0uM0BOnV1zezIAf17p8NitmyY3v22fr1RV+IWSUWzEWhryPdj289LegoCx3d
OYbgV6sKtz8MQrTZWAnGDiynMe1yucNIRCsq1b0rCoMFGo52vFidYKH2SeGnRKQcMq
6lohM+ialbwabDJW8eFBq6jqm+3KcIPyETmpcBLIawX0c21ECQQDotn2hHOTo0IHsx
oxtwA3i8u0OL8dGbrOyBL5xYVRpxas2Sry9WcCLuDCC52VNKszQq+W2xTPriqvuv/V
rBvrtGxLAkEA22LR0G9PNHGIg2K6+lcQWZ8F53cO32cSP3pKfO6A2m2wzii2mPViU6
ONlTJKAB3VlHn13XVxVcaFhdfwcxLARUeQJABq3eC+VH22l2FrR8RvsCpZV8lkKesZ
4gb3jsmoChz/MkwndFNU330+c2ijs84Mces8qLQC22h+du0DZky2QyNPSruwJAPpeB
GSDIzkOeGS4v/oCcj5VJT/Kt8SPFkFDw0UgyjCY22u9GuXk5JnfBS1HfvwzEBOqO9T
IutbRAICGt3ob5CEsQJABLSmUBbUmbILI0ymD9AFmX11t1mijZFnC1X22I5kR4TM511
Oe3j6CFhvyXOg0L9jXKMxcD7GJN73PkglcVypxbzqg==
-----END RSA PRIVATE KEY-----
`
ZHIMA_CERTIFY_CHARSET = "UTF-8" // 编码
ZHIMA_CERTIFY_PRODUCT_CODE = "w1010100000000002978" // 固定值
)
func NewZhimaCertifyClient() *ZhimaCertifyClient {
return &ZhimaCertifyClient{GatewayUrl: ZHIMA_CERTIFY_GATEWAY_URL, AppId: ZHIMA_CERTIFY_APP_ID, PublicKey: ZHIMA_CERTIFY_PUBLIC_KEY, PrivateKey: ZHIMA_CERTIFY_PRIVATE_KEY}
}
// 芝麻认证系统参数
/*
每个接口文档中详细定义了接口业务参数列表业务参数本身是通过系统参数params发送到服务器端的。这里主要描述这些业务参数是以什么格式组合并拼装成了系统参数params的。假设接口A定义了两个业务参数param1和param2值分别为param1_value和param2_value。系统参数params和业务参数的关系为params= URLEncode (Base64(RSAEncrypt(param1=URLEncode(param1_value) & param2=URLEncode(param2_value))))。
首先对于每个业务参数先进行一次URLEncode然后按照URL中传递参数的方式把param1和param2拼接起来使用&和=号)
然后对拼接起来的业务参数进行RSA的加密得到byte数组
然后对RSA加密后得到byte数组进行Base64编码
最后对Base64编码后的params参数做一次URLEncodeURLEncode后的值最终组成了系统参数params的值
*/
// 芝麻认证初始化
func (s *ZhimaCertifyClient) ZhimaCertifyInit(certifyId, certNo, trueName string) (result string, err error) {
// 方法名
method := "zhima.customer.certification.initialize"
// 业务参数
certMap := make(map[string]string, 0)
certMap["identity_type"] = "CERT_INFO"
certMap["cert_type"] = "IDENTITY_CARD"
certMap["cert_name"] = trueName
certMap["cert_no"] = certNo
certMapByte, _ := json.Marshal(certMap)
bizMap := make(map[string]string, 0)
bizMap["transaction_id"] = certifyId
bizMap["product_code"] = ZHIMA_CERTIFY_PRODUCT_CODE
bizMap["biz_code"] = "FACE_SDK"
bizMap["identity_param"] = string(certMapByte)
//bizMap["merchant_config"] = `{"need_user_authorization":"false"}`
// 请求参数
requestParam := getCertifyRequestParams(method, bizMap)
headerMap := make(map[string]string, 0)
logs.Error("初始化芝麻信用API request:" + requestParam)
url := ZHIMA_CERTIFY_GATEWAY_URL + "?" + requestParam
responseBody, httpErr := htools.HttpDo("GET", url, headerMap, "")
logs.Debug("初始化芝麻信用 response:" + responseBody)
if httpErr != nil {
err = httpErr
logs.Error("初始化芝麻信用失败:" + httpErr.Error())
return
}
result = responseBody
return
}
// 芝麻认证查询结果
func (s *ZhimaCertifyClient) ZhimaCertifyQueryResult(bizNo string) (result string, err error) {
// 方法名
method := "zhima.customer.certification.query"
// 业务参数
bizMap := map[string]string{"biz_no": bizNo}
// 请求参数
requestParam := getCertifyRequestParams(method, bizMap)
if len(requestParam) == 0 {
logs.Info("请求参数为空")
err = errors.New("请求参数错误")
return
}
headerMap := make(map[string]string, 0)
url := ZHIMA_CERTIFY_GATEWAY_URL + "?" + requestParam
responseBody, httpErr := htools.HttpDo("GET", url, headerMap, "")
if httpErr != nil {
err = httpErr
return
}
result = responseBody
return
}
// 获取芝麻认证请求参数
func getCertifyRequestParams(method string, bizMap map[string]string) string {
// 系统参数转请求
sysMap := make(map[string]string, 0)
sysMap["app_id"] = url.QueryEscape(ZHIMA_CERTIFY_APP_ID)
sysMap["charset"] = url.QueryEscape(ZHIMA_CERTIFY_CHARSET)
sysMap["method"] = url.QueryEscape(method)
sysMap["platform"] = url.QueryEscape("zmop")
sysMap["version"] = url.QueryEscape("1.0")
// 待签名的参数
waitSignParam := getNotEncryptBizParam(bizMap)
logs.Error("待签名参数:" + waitSignParam)
// 签名
sign, signErr := htools.RsaSHA1Sign(waitSignParam, ZHIMA_CERTIFY_PRIVATE_KEY)
logs.Error("签名:" + sign)
if signErr != nil {
logs.Error("签名失败" + signErr.Error())
return ""
}
sysMap["sign"] = url.QueryEscape(sign)
// 获取加密过的业务参数
params := getCertifyBizParams(bizMap)
sysMap["params"] = params
logs.Error("加密过的业务参数:" + params)
sysParams := htools.MapToUrlParams(sysMap)
return sysParams
}
// 获取芝麻认证业务参数
func getCertifyBizParams(bizMap map[string]string) string {
//1. 首先对于每个业务参数,先进行一次 URLEncode然后按照 URL 中传递参数的方式把 param1 和 param2 拼接起来(使用 & 和 = 号)然后对拼接起来的业务参数进行 RSA 的加密,得到 byte 数组
urlParams := getNotEncryptBizParam(bizMap)
//urlParams := "1"
//RSA加密
paramByte, _ := htools.RsaEncrypt(urlParams, ZHIMA_CERTIFY_PUBLIC_KEY)
//2. 然后对 RSA 加密后得到 byte 数组进行 Base64 编码
base64Param := paramByte
//3. 最后对 Base64 编码后的 params 参数做一次 URLEncodeURLEncode 后的值最终组成了系统参数 params 的值
return url.QueryEscape(base64Param)
}
// 获取未加密的业务参数
func getNotEncryptBizParam(bizMap map[string]string) string {
mapData := make(map[string]string, 0)
for k, v := range bizMap {
mapData[k] = url.QueryEscape(v)
}
urlParams := htools.MapToUrlParams(mapData)
return urlParams
}