diff --git a/backend/app/service/http/http.go b/backend/app/service/http/http.go index 246cdef..518f603 100644 --- a/backend/app/service/http/http.go +++ b/backend/app/service/http/http.go @@ -17,6 +17,7 @@ import ( "quyun/providers/job" "quyun/providers/jwt" "quyun/providers/postgres" + "quyun/providers/wechat" "quyun/providers/wepay" "go.ipao.vip/atom" @@ -31,6 +32,7 @@ import ( func defaultProviders() container.Providers { return service.Default(container.Providers{ + wechat.DefaultProvider(), ali.DefaultProvider(), wepay.DefaultProvider(), http.DefaultProvider(), diff --git a/backend/config.toml b/backend/config.toml index 33f0618..026c091 100644 --- a/backend/config.toml +++ b/backend/config.toml @@ -32,42 +32,48 @@ Bucket ="rogee-test" Region ="cn-beijing" CallbackURL = "https://www.baidu.com" -[Wechat] -AppId = "wx47649361b6eba174" +[WeChat] +AppID = "wx47649361b6eba174" AppSecret = "e9cdf19b006cd294a9dae7ad8ae08b72" Token = "W8Xhw5TivYBgY" -AesKey = "OlgPgMvsl92zy5oErtEzRcziRT2txoN3jgEHV6RQZMY" +EncodingAesKey = "OlgPgMvsl92zy5oErtEzRcziRT2txoN3jgEHV6RQZMY" DevMode = false -# mech + +[WeChat.Pay] +NotifyURL="" MechID = "1702644947" +SerialNo = "4563EC584A35BC84FB27AA4100C934C9A91D59CA" MechName = "佳芃(北京)企业管理咨询有限公司" -ApiCert="""-----BEGIN CERTIFICATE----- -MIIENDCCAxygAwIBAgIUT2xw7W0P1xMKioIAqNwkZSu62OYwDQYJKoZIhvcNAQEL -BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT -FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg -Q0EwHhcNMjUwNDE0MDEzMTM1WhcNMzAwNDEzMDEzMTM1WjCBjTETMBEGA1UEAwwK -MTcwMjY0NDk0NzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTkwNwYDVQQL -DDDkvbPoioPvvIjljJfkuqzvvInkvIHkuJrnrqHnkIblkqjor6LmnInpmZDlhazl -j7gxCzAJBgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAKtux5VS/D35i9byBoU1aUdPHglI2N0kiqugGN6m -v/qWB1QkJBua1AT4KCzsmfbCQPPYvyDyYpUpWPJxxFi9cDwmzn9o7j1syrSG58PD -eUCetEUMvd4KauPDJcuZYJnytM2vcr5xznzkBe4yTw3eeKmVkUgbqFOBs8Xrw641 -uFmAsmQ3TrD0ibrBRAKCPImixB0bxPalGcEau2Pq1TJmkpDpsrkZZ11Bdbf8FXnu -6FXwDIb48nfm7DYrE4rgT+VjZ8OkptbNJZSY0Ncms4RZoBOZI06lJqdfqtgz3Qog -7sf6tYms6+BlGAy/l6UjvobVJ48zh6DI5PuFyxRqi04qfg8CAwEAAaOBuTCBtjAJ -BgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGE -aHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0 -MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFC -NjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEB -CwUAA4IBAQAaEuqWgu/ejf/UEEIWz2nbaGaEY6+ZcvrjwrqQcMp0odDXpCFyRDZ/ -jDeYUAUY3EuKb/LTUtEq2ykPD+6+S41tzfoaDSw2ZEZCkjg8jWJ+4Y4fLv2jXGEI -k5ZDg8Q3mA1/oDsCua9A3ojTyGCScM58rP6fr7fD8ApoM+b+2bUecDnvaU1szR63 -+nHbKc1/CId7ul9YI62ialEjMdutZ1BPCi40K4EjtGf7T2GMnQ1UMbG9pvmkNWQO -9959sZZuJyxyj5g8BHCu5CVADeTyTxrDiyqXOGtxKLLH/6xI/C45Izr8DNC3Fl+i -MYMs5AeLsN7oQ+LWAoHG5rDogzifNKes ------END CERTIFICATE-----""" +ApiV3Key="5UBDkxVDY44AKafkqN6YgYxgtkXP6Mw6" +PrivateKey="""-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+GjWdwRorgQXw +Z8ouZeW8UsUgjiSUPKLJHGOZQESa09xmzm+DVZWNCPEHJvz1bDmSNXVsQUWRE/+y +MwSfe+faq0d4BZiw1ueFbRyj4Vw/x7B2vY0i8yo0VyTnWdC6QZRc+V+dbuPJM1Ok ++Qf2yg+NZhz3XuTWvQOscAc9+f3aj8fhXJQlRmNby736w0iDu9EQFvPnkVs10/lW +RwICvzEbEMq7D2SSXS/lc/qS84eHYYCnH8b3NGNCt7ifSXPJesGT/+pwBKmPef6T +lK0pjgqqiKltP04nYeP7Ujz5r8v/CPebUG6Iuht3EjH84i4UCpcBdI/mD2rJInJ/ +jiiCjP7tAgMBAAECggEAVYVe94BGsKmTrWpT13m513X4/sNTi2iX5xehavExq+GB +trJKEnBvHgqWvBv7EsHESJVKJRBcJn8zucwf2UuZq5MATOtfnLahYzIJ/2PD52GD +bnepxb5VD0Tg8j9CmngkMYtyS1X2na48g+wQfCK8ymTUxSholH5l565iY6xSWn8r +SD/u/EBLv69i40uocG1hUUicrJZ1wc5T0ct3GpfiA1BfH462/dp6mROONdpwM8IT +ltRH4wjIc2nPgE7eNbXlHg+KkqyNNLA+BeN3yn001QwvP6Q0panuCTsVVlvEuGAY +RwXbu/0fHFbppIpgfr7AFGRWKTF66Peq3ozsG9jNgQKBgQDviSJxN2Mpdln4i5F3 +74s8FMtZ5bY63RHHcvJ5/D9G1iDNHFgLJsgdrbAhLqBbqg73EsIT8TsPlAqKPKS8 +EGKBg75MsMSYu7EmzIURV3Gy+Pou9jOkTUfQfblkiV+uJjWQPlBlfksL1bQnfSvZ +Pk1DCwGMb5DMDazAQLP9/wtLYQKBgQDLKz9YHF+wFsnfUjBQngDLCTkxrfxp8y84 +s/z5IRZIEdfxmnaEeWJXYa0oeQumNLSVHrryvHm3vkBgKexN49TWUGIM3q54gi/R +FPXXJKarDEI7C86Th3g+3FPEez5v+CEncmlB9X3kBT0ZFROWD3HHaz2DUKPVmJe1 +eUOtAN0LDQKBgCoulx8i5taFXgCz61EYoQdajhjtp/KjvZ7G8kZjEm2SBcK5DBQi +pzj6vjqJsHmT8AC4j+7dG055/oUresMXi5FNNvTgaC6RVvgDKifMo1wmFkCw4JU9 +erkPetdmja/oUKRvJM9Kt0KFRq1xkIg4PXjh9krZ1sDoY5STkF7ZTA7hAoGAQhPv +xzV7Pac7wwFVK3MoKOD4FBtVRBRO4G9RsKk9OPVsuWyWbWGZRXhEPCyaSFVOAk37 +WaVJJSSghWY9L9wQxh9gtHTcY99bs/HQP0fxWSJkjBW7+ymNR0ybhgTbeslF5zGD +4Gr6peW6SGUdeKnPRJ+xYvsgPgEiHmixRRxJyCUCgYEAoguVZdpDaRDZGGrTghwj +F4kMIyEczFeBZtK2JEGSLA6j8uj+oBZ26c6K4sh/Btc0l6IkiXijXbTaH87s52xZ +im8aIZZ9jDKUFxtjVUL0l9fjRsCLAvaBbWw3z4EdtOGuYlnhNCheeSd+/Lzqrb1q +pnTiwBHnQCMFFL/rNcz/Mmk= +-----END PRIVATE KEY-----""" PublicKeyID="PUB_KEY_ID_0117026449472025041400331572000400" -V3Key="5UBDkxVDY44AKafkqN6YgYxgtkXP6Mw6" # JS pay domain # mp.jdwan.com # quyun.mp.jdwan.com diff --git a/backend/providers/wechat/certs/apiclient_cert.p12 b/backend/providers/wechat/certs/apiclient_cert.p12 new file mode 100644 index 0000000..86eadfb Binary files /dev/null and b/backend/providers/wechat/certs/apiclient_cert.p12 differ diff --git a/backend/providers/wechat/certs/apiclient_cert.pem b/backend/providers/wechat/certs/apiclient_cert.pem new file mode 100644 index 0000000..e4479cd --- /dev/null +++ b/backend/providers/wechat/certs/apiclient_cert.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENDCCAxygAwIBAgIURWPsWEo1vIT7J6pBAMk0yakdWcowDQYJKoZIhvcNAQEL +BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT +FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg +Q0EwHhcNMjUwNDE0MTIwMTI2WhcNMzAwNDEzMTIwMTI2WjCBjTETMBEGA1UEAwwK +MTcwMjY0NDk0NzEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTkwNwYDVQQL +DDDkvbPoioPvvIjljJfkuqzvvInkvIHkuJrnrqHnkIblkqjor6LmnInpmZDlhazl +j7gxCzAJBgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAL4aNZ3BGiuBBfBnyi5l5bxSxSCOJJQ8oskcY5lA +RJrT3GbOb4NVlY0I8Qcm/PVsOZI1dWxBRZET/7IzBJ9759qrR3gFmLDW54VtHKPh +XD/HsHa9jSLzKjRXJOdZ0LpBlFz5X51u48kzU6T5B/bKD41mHPde5Na9A6xwBz35 +/dqPx+FclCVGY1vLvfrDSIO70RAW8+eRWzXT+VZHAgK/MRsQyrsPZJJdL+Vz+pLz +h4dhgKcfxvc0Y0K3uJ9Jc8l6wZP/6nAEqY95/pOUrSmOCqqIqW0/Tidh4/tSPPmv +y/8I95tQboi6G3cSMfziLhQKlwF0j+YPaskicn+OKIKM/u0CAwEAAaOBuTCBtjAJ +BgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGE +aHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0 +MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFC +NjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEB +CwUAA4IBAQC1sIAaLiXzhLJj0XzTFlCiJ3KPggLA4PnbNvzj6sma0ojx8mOHgfHb +hR216vGY0Ll9ZpbAYR9GdEuUWVawZ38Z4GJVFAOCr1pp6DqeM3A/dTk+V4vJawZz +85AtfL1/heU1xsW0AbyPrfDiMHMieHEDNvRvHjQmjZ42aRbHDdRzDH0TIt0paRPB ++ubwCmr947oMe01PWWvF8g032d6NxN4CTPuBuWnJG9OQOm2KQDb4z5GftiJnFbay +KB3WycuqEFbHXVFgn7jrc9+uX0oRE7+iIfGqpcfJrKD93lP2r9AZ6Oxhk3TaNFSQ +u+/uR1Lg1b6vIJqI8otjDH9j5QVLAj5k +-----END CERTIFICATE----- diff --git a/backend/providers/wechat/certs/apiclient_key.pem b/backend/providers/wechat/certs/apiclient_key.pem new file mode 100644 index 0000000..1a8ad54 --- /dev/null +++ b/backend/providers/wechat/certs/apiclient_key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC+GjWdwRorgQXw +Z8ouZeW8UsUgjiSUPKLJHGOZQESa09xmzm+DVZWNCPEHJvz1bDmSNXVsQUWRE/+y +MwSfe+faq0d4BZiw1ueFbRyj4Vw/x7B2vY0i8yo0VyTnWdC6QZRc+V+dbuPJM1Ok ++Qf2yg+NZhz3XuTWvQOscAc9+f3aj8fhXJQlRmNby736w0iDu9EQFvPnkVs10/lW +RwICvzEbEMq7D2SSXS/lc/qS84eHYYCnH8b3NGNCt7ifSXPJesGT/+pwBKmPef6T +lK0pjgqqiKltP04nYeP7Ujz5r8v/CPebUG6Iuht3EjH84i4UCpcBdI/mD2rJInJ/ +jiiCjP7tAgMBAAECggEAVYVe94BGsKmTrWpT13m513X4/sNTi2iX5xehavExq+GB +trJKEnBvHgqWvBv7EsHESJVKJRBcJn8zucwf2UuZq5MATOtfnLahYzIJ/2PD52GD +bnepxb5VD0Tg8j9CmngkMYtyS1X2na48g+wQfCK8ymTUxSholH5l565iY6xSWn8r +SD/u/EBLv69i40uocG1hUUicrJZ1wc5T0ct3GpfiA1BfH462/dp6mROONdpwM8IT +ltRH4wjIc2nPgE7eNbXlHg+KkqyNNLA+BeN3yn001QwvP6Q0panuCTsVVlvEuGAY +RwXbu/0fHFbppIpgfr7AFGRWKTF66Peq3ozsG9jNgQKBgQDviSJxN2Mpdln4i5F3 +74s8FMtZ5bY63RHHcvJ5/D9G1iDNHFgLJsgdrbAhLqBbqg73EsIT8TsPlAqKPKS8 +EGKBg75MsMSYu7EmzIURV3Gy+Pou9jOkTUfQfblkiV+uJjWQPlBlfksL1bQnfSvZ +Pk1DCwGMb5DMDazAQLP9/wtLYQKBgQDLKz9YHF+wFsnfUjBQngDLCTkxrfxp8y84 +s/z5IRZIEdfxmnaEeWJXYa0oeQumNLSVHrryvHm3vkBgKexN49TWUGIM3q54gi/R +FPXXJKarDEI7C86Th3g+3FPEez5v+CEncmlB9X3kBT0ZFROWD3HHaz2DUKPVmJe1 +eUOtAN0LDQKBgCoulx8i5taFXgCz61EYoQdajhjtp/KjvZ7G8kZjEm2SBcK5DBQi +pzj6vjqJsHmT8AC4j+7dG055/oUresMXi5FNNvTgaC6RVvgDKifMo1wmFkCw4JU9 +erkPetdmja/oUKRvJM9Kt0KFRq1xkIg4PXjh9krZ1sDoY5STkF7ZTA7hAoGAQhPv +xzV7Pac7wwFVK3MoKOD4FBtVRBRO4G9RsKk9OPVsuWyWbWGZRXhEPCyaSFVOAk37 +WaVJJSSghWY9L9wQxh9gtHTcY99bs/HQP0fxWSJkjBW7+ymNR0ybhgTbeslF5zGD +4Gr6peW6SGUdeKnPRJ+xYvsgPgEiHmixRRxJyCUCgYEAoguVZdpDaRDZGGrTghwj +F4kMIyEczFeBZtK2JEGSLA6j8uj+oBZ26c6K4sh/Btc0l6IkiXijXbTaH87s52xZ +im8aIZZ9jDKUFxtjVUL0l9fjRsCLAvaBbWw3z4EdtOGuYlnhNCheeSd+/Lzqrb1q +pnTiwBHnQCMFFL/rNcz/Mmk= +-----END PRIVATE KEY----- diff --git a/backend/providers/wechat/config.go b/backend/providers/wechat/config.go new file mode 100644 index 0000000..55fa907 --- /dev/null +++ b/backend/providers/wechat/config.go @@ -0,0 +1,47 @@ +package wechat + +import ( + "go.ipao.vip/atom/container" + "go.ipao.vip/atom/opt" +) + +func Provide(opts ...opt.Option) error { + o := opt.New(opts...) + var config Config + if err := o.UnmarshalConfig(&config); err != nil { + return err + } + + return container.Container.Provide(func() (*Config, error) { + return &config, nil + }, o.DiOptions()...) +} + +const DefaultPrefix = "WeChat" + +func DefaultProvider() container.ProviderContainer { + return container.ProviderContainer{ + Provider: Provide, + Options: []opt.Option{ + opt.Prefix(DefaultPrefix), + }, + } +} + +type Config struct { + AppID string + AppSecret string + Token string + EncodingAESKey string + DevMode bool + Pay *Pay +} + +type Pay struct { + MchID string + SerialNo string + MechName string + NotifyURL string + ApiV3Key string + PrivateKey string +} diff --git a/backend/providers/wepay/config.go b/backend/providers/wepay/config.go index 8a300a6..aad1637 100644 --- a/backend/providers/wepay/config.go +++ b/backend/providers/wepay/config.go @@ -15,14 +15,3 @@ func DefaultProvider() container.ProviderContainer { }, } } - -type Config struct { - Debug bool - NotifyURL string - - AppId string - MchId string - SerialNo string - APIv3Key string - PrivateKey string -} diff --git a/backend/providers/wepay/pay.go b/backend/providers/wepay/pay.go index cfb2462..b5405bc 100644 --- a/backend/providers/wepay/pay.go +++ b/backend/providers/wepay/pay.go @@ -5,6 +5,8 @@ import ( "errors" "time" + w "quyun/providers/wechat" + "github.com/go-pay/gopay" "github.com/go-pay/gopay/wechat/v3" "go.ipao.vip/atom/container" @@ -17,13 +19,19 @@ func Provide(opts ...opt.Option) error { if err := o.UnmarshalConfig(&config); err != nil { return err } - return container.Container.Provide(func() (*Client, error) { + return container.Container.Provide(func(wechatConfig *w.Config) (*Client, error) { // NewClientV3 初始化微信客户端 v3 // mchid:商户ID 或者服务商模式的 sp_mchid // serialNo:商户证书的证书序列号 // apiV3Key:apiV3Key,商户平台获取 // privateKey:私钥 apiclient_key.pem 读取后的内容 - client, err := wechat.NewClientV3(config.MchId, config.SerialNo, config.APIv3Key, config.PrivateKey) +// 1、你最多可同时使用3个有效证书,为减少风险,建议及时作废不使用的API证书; +// 2、API证书包括:私钥文件及公钥证书(配对使用),仅保存在申请证书的电脑本地,无法从系统下载; +// 3、私钥文件名为“prikey_序列号”,公钥证书名为“pubkey_序列号”,序列号请查看上述列表。若无法找到证书文件,可申请新证书。 + client, err := wechat.NewClientV3( + w.Pay.MchID, w.Pay.SerialNo, w.Pay.ApiV3Key, w.Pay.PrivateKey, + wechatConfig.MchId, wechatConfig.SerialNo, wechatConfig.APIv3Key, wechatConfig.PrivateKey + ) if err != nil { return nil, err }