From 5ddfa665e53c0f4b205de42925a51a4f770964bd Mon Sep 17 00:00:00 2001 From: jiangyong27 Date: Fri, 27 Sep 2024 12:35:30 +0800 Subject: [PATCH] alipay uid --- cmd/enterprise.go | 1 + common/config/alipay.go | 88 +++++++++++++++++++++++ conf/alipay/batiao_alipay_public.crt | 43 ++++++++++++ conf/alipay/batiao_alipay_root.crt | 88 +++++++++++++++++++++++ conf/alipay/batiao_app_public.crt | 23 ++++++ conf/alipay/config.json | 17 +++++ go.mod | 4 ++ server/service/qyweixin_approve.go | 101 ++++++++++++++++++++------- 8 files changed, 341 insertions(+), 24 deletions(-) create mode 100644 common/config/alipay.go create mode 100644 conf/alipay/batiao_alipay_public.crt create mode 100644 conf/alipay/batiao_alipay_root.crt create mode 100644 conf/alipay/batiao_app_public.crt create mode 100644 conf/alipay/config.json diff --git a/cmd/enterprise.go b/cmd/enterprise.go index 06fcd1f..db06fbf 100644 --- a/cmd/enterprise.go +++ b/cmd/enterprise.go @@ -9,6 +9,7 @@ import ( func main() { config.LoadServerConfig() + config.LoadAliPay() global.InitGlobal() if err := worker.Init(); err != nil { diff --git a/common/config/alipay.go b/common/config/alipay.go new file mode 100644 index 0000000..05945ca --- /dev/null +++ b/common/config/alipay.go @@ -0,0 +1,88 @@ +package config + +import ( + "encoding/json" + log "github.com/sirupsen/logrus" + "github.com/smartwalle/alipay/v3" + "io/ioutil" + "sync" +) + +type AliPay struct { + Name string `json:"name"` + AppId string `json:"appId"` + PublicKey string `json:"publicKey"` + PrivateKey string `json:"privateKey"` + + //证书加密方式 + IsCert bool `json:"isCert"` + AppPublicKey string `json:"appPublicKey"` + AlipayPublicKey string `json:"alipayPublicKey"` + AlipayRootKey string `json:"alipayRootKey"` +} + +var ( + alipayMap map[string]*AliPay + alipayClientMap map[string]*alipay.Client + alipayMutex sync.RWMutex +) + +func LoadAliPay() { + alipayClientMap = make(map[string]*alipay.Client) + cfgBody, err := ioutil.ReadFile("conf/alipay/config.json") + if err != nil { + panic(err) + } + if err := json.Unmarshal(cfgBody, &alipayMap); err != nil { + panic(err) + } + + for k, v := range alipayMap { + c, err := alipay.New(v.AppId, v.PrivateKey, true) + if err != nil { + log.Errorf("[alipay_notify]支付宝回调错误:%s", err.Error()) + panic(err) + } + + //证书模式 + if v.IsCert { + err = c.LoadAppCertPublicKeyFromFile(v.AppPublicKey) + if err != nil { + log.Errorf("LoadAppCertPublicKeyFromFile %s", err.Error()) + panic(err) + } + err = c.LoadAlipayCertPublicKeyFromFile(v.AlipayPublicKey) + if err != nil { + log.Errorf("LoadAlipayCertPublicKeyFromFile %s", err.Error()) + panic(err) + } + err = c.LoadAliPayRootCertFromFile(v.AlipayRootKey) + if err != nil { + log.Errorf("LoadAliPayRootCertFromFile %s", err.Error()) + panic(err) + } + } else { + err = c.LoadAliPayPublicKey(v.PublicKey) + if err != nil { + log.Errorf("LoadAliPayPublicKey 公钥加载失败 %s", err.Error()) + panic(err) + } + } + + alipayClientMap[k] = c + } + + //log.Infof("wxpay config : %s", goutil.EncodeJSON(alipayMap)) +} + +func GetAliPay(channel string) *AliPay { + alipayMutex.RLock() + defer alipayMutex.RUnlock() + return alipayMap[channel] +} + +func GetAliPayClient(channel string) *alipay.Client { + alipayMutex.RLock() + defer alipayMutex.RUnlock() + return alipayClientMap[channel] +} diff --git a/conf/alipay/batiao_alipay_public.crt b/conf/alipay/batiao_alipay_public.crt new file mode 100644 index 0000000..ba1cb9c --- /dev/null +++ b/conf/alipay/batiao_alipay_public.crt @@ -0,0 +1,43 @@ +-----BEGIN CERTIFICATE----- +MIIDrDCCApSgAwIBAgIQICQIMN/OqnF4oKeLw94+jjANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE +BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs +YXNzIDIgUjEwHhcNMjQwODMwMTQwNTA0WhcNMjkwODI5MTQwNTA0WjCBjDELMAkGA1UEBhMCQ04x +JzAlBgNVBAoMHumHjeW6huWFq+adoeenkeaKgOaciemZkOWFrOWPuDEPMA0GA1UECwwGQWxpcGF5 +MUMwQQYDVQQDDDrmlK/ku5jlrp0o5Lit5Zu9Kee9kee7nOaKgOacr+aciemZkOWFrOWPuC0yMDg4 +NjQxNjY1NTQxNDIyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhRDHTcpyGjKTMeOw +kJl6Slz6nxaN0qXQxehZ0ctEB7u2QsxNwl0cUJpAiKTJwBxh3AnAAOATI/kYjgP5vmA3yaBzLoBj +IvncobVMsKDweOiW37EL+gLo396wq7ynQzZlzMRWAzWMxIniu1947ESHhgh6RGTcMbvU5JeqPlxD +7lwMmba9zWz/5KuoWLTvbRBZn4onMFPuvh9qb5lnzIabopskkVMxRGrmGpjZTTkWYl42IpYZqOkO +ey4ZhnK52sAm/G7n8vfG/SgUkEIHvp+2fvVXtI56d2SaG7FL50vBo/pJSn91sP292zG+hHBJyKdu +eG+Dh/NjaEtvw/CzSoftJQIDAQABoxIwEDAOBgNVHQ8BAf8EBAMCA/gwDQYJKoZIhvcNAQELBQAD +ggEBAHP+m/Mqqc1yiN+aG2lth3WofivwEh/N96AXOfNAXZ489SgpzVHOvUsDjm3TUF1Fcc7izCL2 +gXhGLENG6cbAtAtpL9sa8sNOAnFNHRy9D+BLyAe+olDvMEu5IM2vwBT221mZ8m5VFhCk/QazW/UT +f5elrNZAPED47qp6ckOZ0bMRrLsH+gPqEdV0WrUxBapCI7Z7bqoUmq0t9vOif/Dg2VOUp9vOUGOJ +yrDwoybgYevyfoKK+BhmUWrZrsn588Rj+03O5TIseFZPa29iqBAZly631qFMlo8dmqaYj+oCu1sr +sKNuGtjfGY5nyHZEg/snNSWjDRqI8+WZcoXEsdCg1I0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIE4jCCAsqgAwIBAgIIYsSr5bKAMl8wDQYJKoZIhvcNAQELBQAwejELMAkGA1UEBhMCQ04xFjAU +BgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEw +LwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMy +MjE0MzQxNVoXDTM3MTEyNjE0MzQxNVowgYIxCzAJBgNVBAYTAkNOMRYwFAYDVQQKDA1BbnQgRmlu +YW5jaWFsMSAwHgYDVQQLDBdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE5MDcGA1UEAwwwQW50IEZp +bmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBDbGFzcyAyIFIxMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAsLMfYaoRoPRbmDcAfXPCmKf43pWRN5yTXa/KJWO0l+mrgQvs89bA +NEvbDUxlkGwycwtwi5DgBuBgVhLliXu+R9CYgr2dXs8D8Hx/gsggDcyGPLmVrDOnL+dyeauheARZ +fA3du60fwEwwbGcVIpIxPa/4n3IS/ElxQa6DNgqxh8J9Xwh7qMGl0JK9+bALuxf7B541Gr4p0WEN +G8fhgjBV4w4ut9eQLOoa1eddOUSZcy46Z7allwowwgt7b5VFfx/P1iKJ3LzBMgkCK7GZ2kiLrL7R +iqV+h482J7hkJD+ardoc6LnrHO/hIZymDxok+VH9fVeUdQa29IZKrIDVj65THQIDAQABo2MwYTAf +BgNVHSMEGDAWgBRfdLQEwE8HWurlsdsio4dBspzhATAdBgNVHQ4EFgQUSqHkYINtUSAtDPnS8Xoy +oP9p7qEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQELBQADggIB +AIQ8TzFy4bVIVb8+WhHKCkKNPcJe2EZuIcqvRoi727lZTJOfYy/JzLtckyZYfEI8J0lasZ29wkTt +a1IjSo+a6XdhudU4ONVBrL70U8Kzntplw/6TBNbLFpp7taRALjUgbCOk4EoBMbeCL0GiYYsTS0mw +7xdySzmGQku4GTyqutIGPQwKxSj9iSFw1FCZqr4VP4tyXzMUgc52SzagA6i7AyLedd3tbS6lnR5B +L+W9Kx9hwT8L7WANAxQzv/jGldeuSLN8bsTxlOYlsdjmIGu/C9OWblPYGpjQQIRyvs4Cc/mNhrh+ +14EQgwuemIIFDLOgcD+iISoN8CqegelNcJndFw1PDN6LkVoiHz9p7jzsge8RKay/QW6C03KNDpWZ +EUCgCUdfHfo8xKeR+LL1cfn24HKJmZt8L/aeRZwZ1jwePXFRVtiXELvgJuM/tJDIFj2KD337iV64 +fWcKQ/ydDVGqfDZAdcU4hQdsrPWENwPTQPfVPq2NNLMyIH9+WKx9Ed6/WzeZmIy5ZWpX1TtTolo6 +OJXQFeItMAjHxW/ZSZTok5IS3FuRhExturaInnzjYpx50a6kS34c5+c8hYq7sAtZ/CNLZmBnBCFD +aMQqT8xFZJ5uolUaSeXxg7JFY1QsYp5RKvj4SjFwCGKJ2+hPPe9UyyltxOidNtxjaknOCeBHytOr +-----END CERTIFICATE----- diff --git a/conf/alipay/batiao_alipay_root.crt b/conf/alipay/batiao_alipay_root.crt new file mode 100644 index 0000000..76417c5 --- /dev/null +++ b/conf/alipay/batiao_alipay_root.crt @@ -0,0 +1,88 @@ +-----BEGIN CERTIFICATE----- +MIIBszCCAVegAwIBAgIIaeL+wBcKxnswDAYIKoEcz1UBg3UFADAuMQswCQYDVQQG +EwJDTjEOMAwGA1UECgwFTlJDQUMxDzANBgNVBAMMBlJPT1RDQTAeFw0xMjA3MTQw +MzExNTlaFw00MjA3MDcwMzExNTlaMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVO +UkNBQzEPMA0GA1UEAwwGUk9PVENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE +MPCca6pmgcchsTf2UnBeL9rtp4nw+itk1Kzrmbnqo05lUwkwlWK+4OIrtFdAqnRT +V7Q9v1htkv42TsIutzd126NdMFswHwYDVR0jBBgwFoAUTDKxl9kzG8SmBcHG5Yti +W/CXdlgwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFEwysZfZ +MxvEpgXBxuWLYlvwl3ZYMAwGCCqBHM9VAYN1BQADSAAwRQIgG1bSLeOXp3oB8H7b +53W+CKOPl2PknmWEq/lMhtn25HkCIQDaHDgWxWFtnCrBjH16/W3Ezn7/U/Vjo5xI +pDoiVhsLwg== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIF0zCCA7ugAwIBAgIIH8+hjWpIDREwDQYJKoZIhvcNAQELBQAwejELMAkGA1UE +BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5jaWFsIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IFIxMB4XDTE4MDMyMTEzNDg0MFoXDTM4MDIyODEzNDg0 +MFowejELMAkGA1UEBhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNV +BAsMF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MTEwLwYDVQQDDChBbnQgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFIxMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEAtytTRcBNuur5h8xuxnlKJetT65cHGemGi8oD+beHFPTk +rUTlFt9Xn7fAVGo6QSsPb9uGLpUFGEdGmbsQ2q9cV4P89qkH04VzIPwT7AywJdt2 +xAvMs+MgHFJzOYfL1QkdOOVO7NwKxH8IvlQgFabWomWk2Ei9WfUyxFjVO1LVh0Bp +dRBeWLMkdudx0tl3+21t1apnReFNQ5nfX29xeSxIhesaMHDZFViO/DXDNW2BcTs6 +vSWKyJ4YIIIzStumD8K1xMsoaZBMDxg4itjWFaKRgNuPiIn4kjDY3kC66Sl/6yTl +YUz8AybbEsICZzssdZh7jcNb1VRfk79lgAprm/Ktl+mgrU1gaMGP1OE25JCbqli1 +Pbw/BpPynyP9+XulE+2mxFwTYhKAwpDIDKuYsFUXuo8t261pCovI1CXFzAQM2w7H +DtA2nOXSW6q0jGDJ5+WauH+K8ZSvA6x4sFo4u0KNCx0ROTBpLif6GTngqo3sj+98 +SZiMNLFMQoQkjkdN5Q5g9N6CFZPVZ6QpO0JcIc7S1le/g9z5iBKnifrKxy0TQjtG +PsDwc8ubPnRm/F82RReCoyNyx63indpgFfhN7+KxUIQ9cOwwTvemmor0A+ZQamRe +9LMuiEfEaWUDK+6O0Gl8lO571uI5onYdN1VIgOmwFbe+D8TcuzVjIZ/zvHrAGUcC +AwEAAaNdMFswCwYDVR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFF90 +tATATwda6uWx2yKjh0GynOEBMB8GA1UdIwQYMBaAFF90tATATwda6uWx2yKjh0Gy +nOEBMA0GCSqGSIb3DQEBCwUAA4ICAQCVYaOtqOLIpsrEikE5lb+UARNSFJg6tpkf +tJ2U8QF/DejemEHx5IClQu6ajxjtu0Aie4/3UnIXop8nH/Q57l+Wyt9T7N2WPiNq +JSlYKYbJpPF8LXbuKYG3BTFTdOVFIeRe2NUyYh/xs6bXGr4WKTXb3qBmzR02FSy3 +IODQw5Q6zpXj8prYqFHYsOvGCEc1CwJaSaYwRhTkFedJUxiyhyB5GQwoFfExCVHW +05ZFCAVYFldCJvUzfzrWubN6wX0DD2dwultgmldOn/W/n8at52mpPNvIdbZb2F41 +T0YZeoWnCJrYXjq/32oc1cmifIHqySnyMnavi75DxPCdZsCOpSAT4j4lAQRGsfgI +kkLPGQieMfNNkMCKh7qjwdXAVtdqhf0RVtFILH3OyEodlk1HYXqX5iE5wlaKzDop +PKwf2Q3BErq1xChYGGVS+dEvyXc/2nIBlt7uLWKp4XFjqekKbaGaLJdjYP5b2s7N +1dM0MXQ/f8XoXKBkJNzEiM3hfsU6DOREgMc1DIsFKxfuMwX3EkVQM1If8ghb6x5Y +jXayv+NLbidOSzk4vl5QwngO/JYFMkoc6i9LNwEaEtR9PhnrdubxmrtM+RjfBm02 +77q3dSWFESFQ4QxYWew4pHE0DpWbWy/iMIKQ6UZ5RLvB8GEcgt8ON7BBJeMc+Dyi +kT9qhqn+lw== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIICiDCCAgygAwIBAgIIQX76UsB/30owDAYIKoZIzj0EAwMFADB6MQswCQYDVQQG +EwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UECwwXQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNpYWwgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkgRTEwHhcNMTkwNDI4MTYyMDQ0WhcNNDkwNDIwMTYyMDQ0 +WjB6MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQW50IEZpbmFuY2lhbDEgMB4GA1UE +CwwXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMTAvBgNVBAMMKEFudCBGaW5hbmNp +YWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASCCRa94QI0vR5Up9Yr9HEupz6hSoyjySYqo7v837KnmjveUIUNiuC9pWAU +WP3jwLX3HkzeiNdeg22a0IZPoSUCpasufiLAnfXh6NInLiWBrjLJXDSGaY7vaokt +rpZvAdmjXTBbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBRZ +4ZTgDpksHL2qcpkFkxD2zVd16TAfBgNVHSMEGDAWgBRZ4ZTgDpksHL2qcpkFkxD2 +zVd16TAMBggqhkjOPQQDAwUAA2gAMGUCMQD4IoqT2hTUn0jt7oXLdMJ8q4vLp6sg +wHfPiOr9gxreb+e6Oidwd2LDnC4OUqCWiF8CMAzwKs4SnDJYcMLf2vpkbuVE4dTH +Rglz+HGcTLWsFs4KxLsq7MuU+vJTBUeDJeDjdA== +-----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIUEMdk6dVgOEIS2cCP0Q43P90Ps5YwDQYJKoZIhvcNAQEF +BQAwajELMAkGA1UEBhMCQ04xEzARBgNVBAoMCmlUcnVzQ2hpbmExHDAaBgNVBAsM +E0NoaW5hIFRydXN0IE5ldHdvcmsxKDAmBgNVBAMMH2lUcnVzQ2hpbmEgQ2xhc3Mg +MiBSb290IENBIC0gRzMwHhcNMTMwNDE4MDkzNjU2WhcNMzMwNDE4MDkzNjU2WjBq +MQswCQYDVQQGEwJDTjETMBEGA1UECgwKaVRydXNDaGluYTEcMBoGA1UECwwTQ2hp +bmEgVHJ1c3QgTmV0d29yazEoMCYGA1UEAwwfaVRydXNDaGluYSBDbGFzcyAyIFJv +b3QgQ0EgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOPPShpV +nJbMqqCw6Bz1kehnoPst9pkr0V9idOwU2oyS47/HjJXk9Rd5a9xfwkPO88trUpz5 +4GmmwspDXjVFu9L0eFaRuH3KMha1Ak01citbF7cQLJlS7XI+tpkTGHEY5pt3EsQg +wykfZl/A1jrnSkspMS997r2Gim54cwz+mTMgDRhZsKK/lbOeBPpWtcFizjXYCqhw +WktvQfZBYi6o4sHCshnOswi4yV1p+LuFcQ2ciYdWvULh1eZhLxHbGXyznYHi0dGN +z+I9H8aXxqAQfHVhbdHNzi77hCxFjOy+hHrGsyzjrd2swVQ2iUWP8BfEQqGLqM1g +KgWKYfcTGdbPB1MCAwEAAaNjMGEwHQYDVR0OBBYEFG/oAMxTVe7y0+408CTAK8hA +uTyRMB8GA1UdIwQYMBaAFG/oAMxTVe7y0+408CTAK8hAuTyRMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBLnUTfW7hp +emMbuUGCk7RBswzOT83bDM6824EkUnf+X0iKS95SUNGeeSWK2o/3ALJo5hi7GZr3 +U8eLaWAcYizfO99UXMRBPw5PRR+gXGEronGUugLpxsjuynoLQu8GQAeysSXKbN1I +UugDo9u8igJORYA+5ms0s5sCUySqbQ2R5z/GoceyI9LdxIVa1RjVX8pYOj8JFwtn +DJN3ftSFvNMYwRuILKuqUYSHc2GPYiHVflDh5nDymCMOQFcFG3WsEuB+EYQPFgIU +1DHmdZcz7Llx8UOZXX2JupWCYzK1XhJb+r4hK5ncf/w8qGtYlmyJpxk3hr1TfUJX +Yf4Zr0fJsGuv +-----END CERTIFICATE----- \ No newline at end of file diff --git a/conf/alipay/batiao_app_public.crt b/conf/alipay/batiao_app_public.crt new file mode 100644 index 0000000..e5ad67d --- /dev/null +++ b/conf/alipay/batiao_app_public.crt @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIEmjCCA4KgAwIBAgIQICQIMKRld3DJ6R6L2V1IpzANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UE +BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxIDAeBgNVBAsMF0NlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MTkwNwYDVQQDDDBBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IENs +YXNzIDEgUjEwHhcNMjQwODMwMTQwNTA0WhcNMjkwODI5MTQwNTA0WjBiMQswCQYDVQQGEwJDTjEn +MCUGA1UECgwe6YeN5bqG5YWr5p2h56eR5oqA5pyJ6ZmQ5YWs5Y+4MQ8wDQYDVQQLDAZBbGlwYXkx +GTAXBgNVBAMMEDIwODg2NDE2NjU1NDE0MjIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCxSfleBPz+AOoxV4x4qdQcibhX0IUaDndY+I+rxE2ri0jzGcoNMw/v49R7WXcJAK5jhRsAAmvq +qZGvPhXRhi0WSNLviwiWuHG6XJ9UfIwttE5AXkwEfAmqs86nDd2gEaBZoM/K8cGBjPW3OmSdcAlH +tVuahyYMh6NrkHJiyeIjnja/lsOThGzPex6Kns0vp9jEwkM2A9uUShL7c59psGYYpChVcEcfG9Lp ++pu4YgABk4oDUquCXdG0g+we350mu01QSPF2l8I/hgpwtXE8ei1yo1LMKfXYnEu88D4gwILB2SbT +PMmoYAyijd39Zml4dlH+8CnJYxj4u4y2CVGpB4mhAgMBAAGjggEpMIIBJTAfBgNVHSMEGDAWgBRx +B+IEYRbk5fJl6zEPyeD0PJrVkTAdBgNVHQ4EFgQUXxMOzkfBXyKCcFeiMXEaugJfJIIwQAYDVR0g +BDkwNzA1BgdggRwBbgEBMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9jYS5hbGlwYXkuY29tL2Nwcy5w +ZGYwDgYDVR0PAQH/BAQDAgbAMC8GA1UdHwQoMCYwJKAioCCGHmh0dHA6Ly9jYS5hbGlwYXkuY29t +L2NybDkyLmNybDBgBggrBgEFBQcBAQRUMFIwKAYIKwYBBQUHMAKGHGh0dHA6Ly9jYS5hbGlwYXku +Y29tL2NhNi5jZXIwJgYIKwYBBQUHMAGGGmh0dHA6Ly9jYS5hbGlwYXkuY29tOjgzNDAvMA0GCSqG +SIb3DQEBCwUAA4IBAQABbwU0AHj6vPS5mfYBdnoaaBgp9mJiniHY9Ue12UC7C3KHDAgGEnvQOo7p +++xnAW0CuFGXnmbmP6wb6vo+2UXSDAUgsVDWF2eckkR1OI965KXZalQ05v937lXA6aMZVC0UzNSP +vaDQoEtiaK/M/+gfdylbteOtOabrs4mWSvPx6DwudZKX11XTfPeHDkuI/Vzm+FbqaIdPYREc2ogL +yhFuT0ptwXEogLI+S9gdfgO2XHe5HDKjCqx3KOOrqLrPgv+Zm2PTe0M3FAvukGEL4ObUfANI9MQ5 +ksGW520Ksw+lKPr2YEGVFo/tH1BVcbknJsNPoXZKw6jnnsDAD9Ry76PO +-----END CERTIFICATE----- \ No newline at end of file diff --git a/conf/alipay/config.json b/conf/alipay/config.json new file mode 100644 index 0000000..8108af8 --- /dev/null +++ b/conf/alipay/config.json @@ -0,0 +1,17 @@ +{ + "batiao": { + "isCert": true, + "appPublicKey": "conf/alipay/batiao_app_public.crt", + "alipayPublicKey": "conf/alipay/batiao_alipay_public.crt", + "alipayRootKey": "conf/alipay/batiao_alipay_root.crt", + "name": "重庆八条科技有限公司-天眼招标", + "appId": "2021004108682468", + "privateKey": "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCxSfleBPz+AOoxV4x4qdQcibhX0IUaDndY+I+rxE2ri0jzGcoNMw/v49R7WXcJAK5jhRsAAmvqqZGvPhXRhi0WSNLviwiWuHG6XJ9UfIwttE5AXkwEfAmqs86nDd2gEaBZoM/K8cGBjPW3OmSdcAlHtVuahyYMh6NrkHJiyeIjnja/lsOThGzPex6Kns0vp9jEwkM2A9uUShL7c59psGYYpChVcEcfG9Lp+pu4YgABk4oDUquCXdG0g+we350mu01QSPF2l8I/hgpwtXE8ei1yo1LMKfXYnEu88D4gwILB2SbTPMmoYAyijd39Zml4dlH+8CnJYxj4u4y2CVGpB4mhAgMBAAECggEBAJY34c1iWKM4TzdjwSh0bb+IieQOUNlVLJb8dW/LMyyJJlSlo2gvve87kky573x3UUwN+mS1qI77AvADoSUZlZZuOhyyJ6Ldwa9wz6gcqAIJ5svvmmWqW96B4DX4L7Nze/S1p5uD4LxOndyU46/qwFI8PtPec8TmIPgBOoquGKin+u0uRrl25vQ/3b+NkGwjYCPs2VmpaBnIrdtXtqjE8HlGFApZ0ekeyiAJ/fGisUqqkoFFZ+b6jwmO3r2/sW7b+XGX65KHbF/kStG3cVfumvXBWwufc4w+LcPHsdRtuGjxXU8zhRh1uGmokrnCUWK7X710vl/gZvhqsWGQ4hz+kKkCgYEA3EwWbzFjpfT6AUpXcvQhnzvxqp3C31HN+aASKYROhuAomYsjy2u8iHhmqoDMubA80XbU8pA5loSHsX+uQRnRnWTxR/UmhBVi5ImFdksC1KyDqgk4xiuvU5zwxXrmzySSUziYidXh5cqOKaHRMDAQnnmslWVIgYHQK+Siow0vmvcCgYEAzgWERr0RqbGeNp5f3CgD5TWWn16IGioofdbLrX3qJDI/Scix8Qh7JgwsU0RSkjjCGohz+v92cFUWg7eRskjpZAeM0hdQEs4R8vO1Ec2XKWYOeBCcdL7oCU/MVBISCI6w+AV7X+ZI7bC5rM4JxYSQp/tyYeOPl7Wu5PO6Eke3AicCgYBdhXeosMDq/Tr9PUAurvFvFhWcJulJwQK+THQpZ9+mZpcVx/nkK9KX5PVAwPkog2buTZJNf2jTO2QXuGqTfJB+TxIXSD2XqTSYbMFZ3LJQ8wPaNZwClR0TU/bq/yfpHE96QPaQ3VnPIdSEXAvgdyc2/9SCf8LuJ9vmJmPc8IYbNQKBgQCnZ9otNNLWZcqerSBNn4JSzLGgvEqxoBIY9uG4DvmkAeRlSxw0NGUE7J1T58+Em3Q15S0BBnYyHyHVU+Oi0BY9vtjRmjnpneL93MQEPF+ZNyGItE69mqancl0g7zISHAh28NVofpJB+flWDnHoOqjkprAyFJwIdYww5E8NLZLqvwKBgQDE/gxwqs5SJGstD79nRmy5h9a4JiaQC6+iuXRR38rQxqdYYqA4LKg/u1W/47ItlHs68kFsUbyyyQ93vA8uFVRFjAesuc46We0s5YtH9Y8ww6TnYkxWrqJ6a5ApoNnZdlW/1+/2dHXumhToYRIYta5RBPOw+9Y67/VXxGpbBJZiZQ==" + }, + "batiao2": { + "name": "重庆八条科技有限公司-天眼招标", + "appId": "2021004137639439", + "publicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA67hTfcwAP1wzJkUouuVB4Hp9rQlyopKa5Zvvz2M6kRB87BGnC385IoTMTGtZylsm06TmgRTqf5ES+U43YK3+Kqu+ccZAH5oWnD1auXJQK+IfaxSphT/BY7RBYKGK2lPMRgy0kCtshogLX6n4X3RPMAAfK4JbO6ZjLvmH2AhZ5VVXh2VUEWIpYAeZ0rWKkVbpnoCJ2BFaFnFqetHN16fY95F+dmXJMRWpCMhQfIlKWGlI37VvVGeplrnC1YarKXiw2DK+Agh93ecyZG3AfLJwRWmdL8lbbqKQJHmG5QKMB5syqG14HsOMcA6oBvcu6u+4/XY0U13W4vs8cV6Rz60Y7QIDAQAB", + "privateKey": "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCQZ+RKi0pnLEncBoPskaSAYLswWR95J7Z7sizqAVjuZNd8uEBRoGDM1MIxbMMdsh76zINQEfW0lv0Ej2Gtu5baYEk9K7sYOKAJSoB6ousQB636kknN1a2sufmYSJDGfrYHnVdBExeEwa9UsbihKP0rTKaaHFpHAiu/KFD1UQTyb2g2p1NmdOvc7WkNuectfgiCquURUWEud9UkY5vXYfIb67dh7/QMAlpxvWkUAQRhxUjJvSCU5DCseZrrKUivprmasDXjNtEtKE1yH/1hvZYRcdu4N7ie98QFSkMozr0+5cPJNOGA65hypSTNGrSyAFH/MPEJFQgz7G36T1e53KfdAgMBAAECggEAPX7QvGIHBFra9UUdBzCaskT/Uj6R5aFg19pvwBNk0NjG34kDcv9uWaw9KpkbmljRUpKnVQDg9s/Z3ghFW5voSQT6C3/FBDKRDIPapN8eZUwv7eZAYdSeSlFElnJInQ8265U4pDDCMjndNZ8ddhwjfD3/MN/kHhsxkA1WNLIU/jyIsk1iqU89XH8PyrWoG1ZFBOQp5anbhxDl0QZUBFB0dRhpv+jjA566eBM7A6Ny+6UCu8NteobyDoWlFJMulyh6OWevOXqfvkKEy8WwSg4KFk5319xFLV7eQEiPpj1dxW1I5X3iNQlxkZw4beUSnDvG5tKeRYnYIvqy8vOrKXj/gQKBgQDU9E0udxJyz2s+0DehZAk8JTt+H69aPlL6musbPFTBMgzU36MwUlm33/VItABV80Kdq5+o/0PSOpIUQmg25fdb64I6OuaLM4+XlcpXMtVIJ39+KC1Il7kBym8TIk8ZS58bcgtv/mWNy/128oEg86Jt1COxaXpUxWhVmruFHonXoQKBgQCtmG19YXmnvCJDGa0jXwNdpj8CUkA58q5Ootv9HmZZ+9T4dyPa6xMCeLTYPgqLo45XfhP9Uoidk3z/j+cr1ch8g8Qm9cvmiNDwNutdaN3T7rrS12TX1FrSRYHkbROPDDTxM3bA310GaaifoEQsyWqREUWTt4/vZ3toyxgCS0y2vQKBgAMNGQoAZMBGXogA3bsvPr6g3fBZrd6CJBg5HgM+4wv9lpd6ONFZbLWovM/03Ehe+uZdbiUyuxsJAczOgsW+l8O2ZSBGdcUq0PTgDY0gSlQFVNtO4g83NUxkRSEmDbIUFkyDXsyU/YmBkbkhkl4Rf5NJRdWl6D3Mskj/tY4buOfhAoGAN/AMKADG8NPgvnqBngo5zW2KlDbo10NqA5DbDn9DP++0OrQ5a4ugPoWi0KN9Rm3Xqj3INzLnLs+d0cQPG8LxrZ3QETXXFFw155Hq2di20ln0/YfGyP12npcjOfYj/U5TqP2KYLAZC730RiugjEYC/ufv4Z+e0+gmjigTfnnBKIkCgYEAgXhspwHUJTGMUYxcgpPBzGs6YS9ATIuN410P5Uz9aRSsPDJIsrtwe0D3m60bSkPxlU99KCZFA+gIt6IkTfmGKa3Q37PX56cjnOLu+k9AJgIX5h1LlZv03t64dKOcMS/X90OKjRWkrzP5FVnjciSEFlOedcXnSh3gMRDBzoXYM3k=" + } +} \ No newline at end of file diff --git a/go.mod b/go.mod index eeedae2..47329a7 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5 github.com/sirupsen/logrus v1.9.3 + github.com/smartwalle/alipay/v3 v3.2.23 github.com/smbrave/goutil v0.0.0-20240724121721-dd5a9ae0b015 github.com/spf13/cast v1.7.0 github.com/spf13/viper v1.19.0 @@ -66,6 +67,9 @@ require ( github.com/robfig/cron/v3 v3.0.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/smartwalle/ncrypto v1.0.4 // indirect + github.com/smartwalle/ngx v1.0.9 // indirect + github.com/smartwalle/nsign v1.0.9 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/speps/go-hashids v2.0.0+incompatible // indirect github.com/spf13/afero v1.11.0 // indirect diff --git a/server/service/qyweixin_approve.go b/server/service/qyweixin_approve.go index 6a49196..6979703 100644 --- a/server/service/qyweixin_approve.go +++ b/server/service/qyweixin_approve.go @@ -1,6 +1,7 @@ package service import ( + "context" butil "enterprise/base/util" "enterprise/common/config" "enterprise/common/dao" @@ -9,8 +10,11 @@ import ( "fmt" "git.u8t.cn/open/gosdk/qyweixin" "git.u8t.cn/open/gosdk/wechat/message" + "github.com/gogap/errors" log "github.com/sirupsen/logrus" + "github.com/smartwalle/alipay/v3" "github.com/smbrave/goutil" + "github.com/spf13/cast" "strings" ) @@ -153,6 +157,61 @@ func (a *Approve) handleCheckin(detail *qyweixin.ApproveDetail) { } } +func (a *Approve) handleRefundWxpay(data *model.ApprovalRefund) error { + openid, err := a.approveClient.GetOpenid(data.Username) + if err != nil { + log.Errorf("GetOpenid error :%s", err.Error()) + return err + } + + var req qyweixin.PayReq + req.BillNo = fmt.Sprintf("BX%s%s", data.SpNo, butil.CutTail(data.Username, 12)) + req.Title = fmt.Sprintf("【%s】报销", data.RefundType) + req.Openid = openid + req.TotalAmount = int64(100 * data.RefundAmount) + qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{ + Corpid: config.GetConfig().QyWeixin.Corpid, + Secret: config.GetConfig().QyWeixin.PaySecret, + Agent: config.GetConfig().QyWeixin.PayAgent, + SerialNumber: config.GetConfig().WxPay.PaySerialNumber, + ApiKey: config.GetConfig().WxPay.PayApiKeyV2, + MchId: config.GetConfig().WxPay.PayMchId, + CertPem: config.GetConfig().WxPay.PayCertPem, + KeyPem: config.GetConfig().WxPay.PayKeyPem, + }) + if err = qyPay.PayMoney(&req); err != nil { + log.Errorf("pay error[%s] :%s", goutil.EncodeJSON(req), err.Error()) + return err + } + return nil +} + +func (a *Approve) handleRefundAlipay(staff *model.StaffInfo, data *model.ApprovalRefund) error { + + cli := config.GetAliPayClient("batiao") + var req alipay.FundTransUniTransfer + req.Remark = data.SpNo + req.OutBizNo = fmt.Sprintf("BX%s%s", data.SpNo, butil.CutTail(data.Username, 12)) + req.TransAmount = cast.ToString(data.RefundAmount) + req.ProductCode = "TRANS_ACCOUNT_NO_PWD" + req.BizScene = "DIRECT_TRANSFER" + req.OrderTitle = data.RefundRemark + "报销" + payee := new(alipay.PayeeInfo) + req.PayeeInfo = payee + payee.IdentityType = "ALIPAY_USER_ID" + payee.Identity = staff.AlipayUid + + rsp, err := cli.FundTransUniTransfer(context.Background(), req) + if err != nil { + panic(err) + } + if !rsp.IsSuccess() { + log.Errorf("FundTransUniTransfer error :%s", goutil.EncodeJSON(rsp)) + return errors.New(goutil.EncodeJSON(rsp)) + } + return nil +} + func (a *Approve) handleRefund(detail *qyweixin.ApproveDetail) { newData := new(model.ApprovalRefund) newData.From(detail) @@ -176,39 +235,33 @@ func (a *Approve) handleRefund(detail *qyweixin.ApproveDetail) { return } - // 支付费用 - - openid, err := a.approveClient.GetOpenid(newData.Username) + staff, err := dao.NewStaffInfoDao().GetByUsername(newData.Username) if err != nil { - log.Errorf("GetOpenid error :%s", err.Error()) + log.Errorf("db error :%s", err.Error()) return } - var req qyweixin.PayReq - req.BillNo = fmt.Sprintf("BX%s%s", newData.SpNo, butil.CutTail(newData.Username, 12)) - req.Title = fmt.Sprintf("【%s】报销", newData.RefundType) - req.Openid = openid - req.TotalAmount = int64(100 * newData.RefundAmount) - qyPay := qyweixin.NewAppPay(&qyweixin.PayConfig{ - Corpid: config.GetConfig().QyWeixin.Corpid, - Secret: config.GetConfig().QyWeixin.PaySecret, - Agent: config.GetConfig().QyWeixin.PayAgent, - SerialNumber: config.GetConfig().WxPay.PaySerialNumber, - ApiKey: config.GetConfig().WxPay.PayApiKeyV2, - MchId: config.GetConfig().WxPay.PayMchId, - CertPem: config.GetConfig().WxPay.PayCertPem, - KeyPem: config.GetConfig().WxPay.PayKeyPem, - }) - if err = qyPay.PayMoney(&req); err != nil { - log.Errorf("pay error[%s] :%s", goutil.EncodeJSON(req), err.Error()) - return + // 支付费用 + if newData.RefundAmount > 200 && staff != nil && staff.AlipayUid != "" { + err = a.handleRefundAlipay(staff, newData) + } else { + err = a.handleRefundWxpay(newData) } + + var title string = "【报销成功】" + if err != nil { + title = "【报销失败】" + } + message := make([]string, 0) - - message = append(message, fmt.Sprintf("【红包发放】[%s]", newData.RefundType)) + message = append(message, title) message = append(message, fmt.Sprintf("发放金额:%s", fmt.Sprintf("%.2f", newData.RefundAmount))) + message = append(message, fmt.Sprintf("费用类型:%s", newData.RefundType)) message = append(message, fmt.Sprintf("员工名称:%s", newData.Username)) message = append(message, fmt.Sprintf("费用说明:%s", newData.RefundRemark)) + if err != nil { + message = append(message, fmt.Sprintf("异常:%s", err.Error())) + } if err := global.SendMessage([]string{"jiangyong"}, strings.Join(message, "\n")); err != nil { log.Errorf("send message error :%s", err.Error())