初始化项目,复制原投票系统后台代码
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
"vote-video-api/config"
|
||||
)
|
||||
|
||||
// 创建客户端
|
||||
func createClient() (*core.Client, error) {
|
||||
mchId := config.C.Wechat.Pay1281030301.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1281030301.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1281030301.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := config.C.Wechat.Pay1281030301.PrivateKey // 商户私钥文件地址
|
||||
|
||||
if mchId == "" {
|
||||
return nil, errors.New("商户号错误")
|
||||
}
|
||||
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, errors.New("微信支付生成失败")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
|
||||
opts := []core.ClientOption{
|
||||
option.WithWechatPayAutoAuthCipher(mchId, mchCertificateSerialNumber, mchPrivateKey, v3ApiSecret),
|
||||
}
|
||||
|
||||
client, err := core.NewClient(ctx, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.New(err.Error())
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// WxPayResult 支付结果
|
||||
type WxPayResult struct {
|
||||
OrderStatus int `json:"order_status"` // 订单状态(1:待支付 2:已完成 3:已取消)
|
||||
PayStatus int `json:"pay_status"` // 支付状态(1:未支付 2:已支付 3:支付中 4:支付失败 5:支付超时 6:支付关闭 7:已撤销 8:转入退款)
|
||||
PayTime *string `json:"pay_time"` // 支付时间
|
||||
}
|
||||
|
||||
// WxPayRefundResult 退款结果
|
||||
type WxPayRefundResult struct {
|
||||
RefundStatus int `json:"refundStatus"` // 订单退款状态(0:无退款 1:申请退款 2:退款中 3:退款成功 4:拒绝退款 5:退款关闭 6:退款异常 7:部分退款)
|
||||
SuccessTime *string `json:"successTime"` // 退款成功时间
|
||||
}
|
||||
|
||||
// HandlePayStatus 处理支付状态
|
||||
func HandlePayStatus(t *payments.Transaction) (w *WxPayResult, err error) {
|
||||
w = &WxPayResult{}
|
||||
|
||||
switch *t.TradeState {
|
||||
case "SUCCESS": // 支付成功
|
||||
w.OrderStatus = 2
|
||||
w.PayStatus = 2
|
||||
w.PayTime = t.SuccessTime
|
||||
case "CLOSED": // 已关闭
|
||||
w.PayStatus = 6
|
||||
case "REVOKED": // 已撤销(付款码支付)
|
||||
w.PayStatus = 7
|
||||
case "USERPAYING": // 用户支付中(付款码支付)
|
||||
w.PayStatus = 3
|
||||
case "PAYERROR": // 支付失败(其他原因,如银行返回失败)
|
||||
w.PayStatus = 4
|
||||
default:
|
||||
return nil, errors.New("未知支付状态")
|
||||
}
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// HandlePayRefundStatus 处理退款状态
|
||||
func HandlePayRefundStatus(r *refunddomestic.Refund) (w *WxPayRefundResult, err error) {
|
||||
w = &WxPayRefundResult{}
|
||||
|
||||
switch *r.Status {
|
||||
case "SUCCESS": // 退款成功
|
||||
w.RefundStatus = 3
|
||||
if r.SuccessTime != nil {
|
||||
successTime := r.SuccessTime.Format("2006-01-02 15:04:05")
|
||||
w.SuccessTime = &successTime
|
||||
}
|
||||
case "CLOSED": // 退款关闭
|
||||
w.RefundStatus = 5
|
||||
case "PROCESSING": // 退款处理中
|
||||
w.RefundStatus = 2
|
||||
case "ABNORMAL": // 退款异常
|
||||
return nil, errors.New("退款状态错误")
|
||||
default:
|
||||
return nil, errors.New("退款状态错误")
|
||||
}
|
||||
|
||||
return w, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDR4fiYRUjnLQA+
|
||||
TPMslDvQIIyZm4ajWFcSXg6yozhdi/O+vuRhwgyeGXsE4SpvuxkK4HPZaocrsjqe
|
||||
68Y46DyhudzXIBy50IF2UeN5ilj7ydq5TJbBOi1iOF1lgOUNK6DGiOQ+folVNKyN
|
||||
sjrsA3RHUKHF/JdOfcpSGzvV79FnmjSll/KsdxEc9LCiAa5t7GYA9Hx7AIDG4i8b
|
||||
03d5EJXvE8BGUZQItE6VIpHwyySTHtGQkPyI6lqMKt2Jlx0TFHu0GkTEmhuA2Z5C
|
||||
5gOqYWclQO+X2ORgulL9Q3mNcpfy9uBynI/CJDbSvVTkNfwYB0Ny1knu/+in7C6p
|
||||
IPJYfZpPAgMBAAECggEAWb5tJPcjSC5W10ziAiLUPJdeZ2Q4OupQOPtc/4eJV367
|
||||
V8maMC7gZE3y61A4bBQtjhgRkVrat5V7OW8JkFXFb0XhJ1+EyPNeGDDFureseuWC
|
||||
EA+uuqrcsw306a0mw+3uzlXEevByWquuSNx4E2katE/HDLiIHjjtZRReDomAGfLw
|
||||
vLNZ40RgdNSXmwpVRoHOZnvX+C2Hxh4fKsrxs1HRCjFsSpTxKwsK6/Kdudj4hsaO
|
||||
Z5glqf4qopPlQIIkToxOe5p7ukwo7vqaqogixx3jOjruOMpzxZ24wU5AxneLcOYr
|
||||
ZC1659Uwv96TsKpueakWw0lq3TXkv9Qs+wDNI+NC6QKBgQDx4hWXplLYPYwgGgxG
|
||||
L9Pk+If9aDS9wj78JUaYBXKR5atXmf/62ufahW4IEDfmMugC1bm9MoYC7CmHv1nk
|
||||
nxckB84B20NOSiaxbkOaJuMHDtnNeXCmL8Gvtb8fTni1AM/g6XEleEw1r40LNZAq
|
||||
kdyQ1+OUFhRQGOvAe1SRr1rdGwKBgQDeIcauwMPkc3Seh6Fb66FQ4Lgmt1GvvuiG
|
||||
UJiwgwPFbEaKKczBHBL6hlKoAFweFa2Qw2xJ0H8jwb8RnkkNcAKYUyMc2wi85+Ih
|
||||
d568pvXMdYl4DGeGdd/sXKf4dGDjcb2AHzNfDuklbCsAojtO3pLWOs5U/RSKe8ps
|
||||
hhWa8nPO3QKBgQCIxuKU3X1tP+hz4qbcLYFxscQcXIeuYiABrwZrQnFV5Pxtzex9
|
||||
Krn+zIK61oj1iAXATKD6Ro6XKnoVg/POHtQUEMHCNP2rUKzumj5p9eFdBV3OHgTA
|
||||
RLMOrARGLLZ/C9WBBiBwIsVdekaUdxZtrAuAcEQFYjLcVCtDrbnVo8YKzwKBgEsg
|
||||
V0cBMP+RwM5hBsTE45Er/3wwofLzeUb7+Tgxh1P887qEuphRO2X5ifkB7iXKpSIB
|
||||
xh0M5AMe4tU9mG1wBaCo9YYr2j+xmTxCbbBWM2mMEwtD/rtuIGabS7/u9FnYPQQZ
|
||||
CVHMBDRA6iZTuAVLp5PG3cPGuGzBw0uC6cm22E4NAoGAKrbg3nFPKtzBJZ8Z0iNH
|
||||
G2gNotmHXbd4+gs4e3Iz9xsEabm4wCoEibNojNdMkX8zX267ebgfvesGEobROjW9
|
||||
Intvh39xi3aQ2Q5gvXzKdY0lDzgVvQ7udmLQ4dCUyYnpLr7Yac0asRxLge2esCWV
|
||||
x2uW2YTiUW3zsbHN/N/vJ5I=
|
||||
-----END PRIVATE KEY-----
|
||||
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIELjCCAxagAwIBAgIUfewObFfg3HHwd/AvUkBlZq85vrswDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjMwMzAxMDExNzE3WhcNMjgwMjI4MDExNzE3WjCBhzETMBEGA1UEAwwK
|
||||
MTYzNjY0NDI0ODEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQL
|
||||
DCrljJfkuqzmrKPmrKPnm7jnhaflgaXlurfnp5HmioDmnInpmZDlhazlj7gxCzAJ
|
||||
BgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQAD
|
||||
ggEPADCCAQoCggEBAK7x9ywApasrs+xIt0XxHhYOK4xZeuNEj5o7pzTcZMRkd6CB
|
||||
1eX2ydlUfDe+FcNS03cwLNtUeAfrZXlhA807b4HuReaFqCrbt87hfIF/lOBpePdN
|
||||
sSr8Wi6OKfPakuLNZ4RCOdlvgxPMhOf2b9VFQwns8h72H6JrFz7xR+Heundy3KGH
|
||||
kEoG2qcl7nKyhkUVSRSH4/yzsxsDIwkpXjEiSL87E+A6GKik7jphYc+vfV9NURiA
|
||||
JwbVWbQMhpj3YLRxgXadLS4xMryB59fYKm+VFMNg/jSZG55Jz2DW02aR2h3KjegY
|
||||
SGA9qMKojkFVOrZvxKWOvtEWw2JQ/1dRvzYpgw0CAwEAAaOBuTCBtjAJBgNVHRME
|
||||
AjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGHhoGEaHR0cDov
|
||||
L2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0xQkQ0MjIwRTUw
|
||||
REJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0NzFCNjU0MjJF
|
||||
MTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3DQEBCwUAA4IB
|
||||
AQCBjjBeJTRtnsIISCfoQ7pj70dil5LTBNjpzV9swGOG7sY9dTMbHV0K2BUyRvbD
|
||||
eY2fuCcr3Qt3L1RykyomKbxD4O6b/ZPLTkiq2m+hq34g2Ig7zUx0a0sNKf/NPAq6
|
||||
6pVu5/XdIKYXz2OsByBI8aN2hkcUApmM1qlm+gb4FSmTzkdHaFRblhDlKfiRdAw8
|
||||
T4yliaOFovqhf/S8o5Xa76kQMOb3uJ/oE4KX02kp/ig5wZKj9nay46AyovBXOj+Z
|
||||
0oaeIPFDXCPzZV7LA4E45zDl43fL8r+9OzaVprRZ9ASO0cgnPsHyS+o/mpMEBOR4
|
||||
NIwdIaqYRQ/Rh6eZQvrqDZ4r
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCu8fcsAKWrK7Ps
|
||||
SLdF8R4WDiuMWXrjRI+aO6c03GTEZHeggdXl9snZVHw3vhXDUtN3MCzbVHgH62V5
|
||||
YQPNO2+B7kXmhagq27fO4XyBf5TgaXj3TbEq/Foujinz2pLizWeEQjnZb4MTzITn
|
||||
9m/VRUMJ7PIe9h+iaxc+8Ufh3rp3ctyhh5BKBtqnJe5ysoZFFUkUh+P8s7MbAyMJ
|
||||
KV4xIki/OxPgOhiopO46YWHPr31fTVEYgCcG1Vm0DIaY92C0cYF2nS0uMTK8gefX
|
||||
2CpvlRTDYP40mRueSc9g1tNmkdodyo3oGEhgPajCqI5BVTq2b8Sljr7RFsNiUP9X
|
||||
Ub82KYMNAgMBAAECggEAT7uNyGs/FkVjykPV67WZ3bl1lZDOljgQLt4TNd9gubWE
|
||||
ZA3om9efZULBHnKu3oeoQ0EcoJXd4tYhOHHD1szI5HHhP9AYtffPzSUtpqOsCZ9o
|
||||
d2XcYlgDDgbTDgXHPkEZdcjtLrFJD0P+Ku5BR/U6OZLZQs0v28ltHc2/0iy91WQt
|
||||
iB/NSf88dY1L5RVZc7dZfb8nFB2/BsITUXDFJpzdim3AXKvNYzDajs/yuoTp5r/b
|
||||
2EOjUIGPP55W/8iPwbezgDToF79toum6V7yUpCq5P+QQvnnbJfoc1yXB48zHjmgP
|
||||
I2P1cDVtFs+V9Edb6qsU3e4CMyBQg5Uykk3TUqZRIQKBgQDnXgGk8XnI1kG9jZMR
|
||||
wMkra87Dx76vrBdM47n+c2I1xubM9WSeSUxtXGyryTwJ9i6/BUyc3Eyb2wi4Q8AK
|
||||
1ZIEFhvIUkBJpUgevAksj4eX6z0qDwDc3ZhgAAWOplnOCCyJuOBKmZks4GaQb4Gv
|
||||
/aSFVQ9jefOc5e9RIDNzkHFkaQKBgQDBkigvmusjad95Jt34TwyE4Dr9z2LzBker
|
||||
6ebcyQmv4YdKvq0KaaVMrroH7pNu7CSFrj4CGqdS/Gg1BtK8Xaxn+gEWT6RPcsi1
|
||||
mPwy/7oiK0GodzNI6RW5HDZEHKG2icEb4ycDnHeLfThKmP/gckPifjcJHrP5OX1A
|
||||
V6qrq4iFBQKBgGdgB1gNVJ65rJHnCckq3Dd8advsCXUwbRC7x0S7hSwF/OWi1xwq
|
||||
H+3VF/EBbsP8rRJIadzESa5xhUnfa5Trq9wLjMpKhdLh+IFS/r5cOvdT8fYy0e3d
|
||||
TNHH8LO1+/YkjNHUOtLaIih88xah284ohDPWt5N4z7JQwkb7HkIKTb/RAoGARt51
|
||||
7Afx8sM+WCLMva5jTPqzXl1hQsyXzO8T4N2RuFz/pXPt8pP/OvX1khXc0I2QSYkj
|
||||
lq2feRiEJnXbDa/WATNc1ohOBfBmX2YlX56UzRG9Nip+EkGT/HPBwmohIq2Ij+c4
|
||||
T3AnrGAqDdW6SLhM9k1zZNli1uofW0E9cSCaGOkCgYAI29eelAwUxpbDXJB6vSyr
|
||||
LBvDV+C+/3OW4AjlJ5lWSzY8oMn21Xzp03MwXOXOSFuR6vTMkJDKJ3zIDHBt9vJ2
|
||||
evNmfMKzqNdsvNjORb79GAZ0paBF1XGzXvPO9JSUi6oZxNg+pW8oxIzx0xFIgtZL
|
||||
PxnzFj2IbraxYwuR1CI6rQ==
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEFDCCAvygAwIBAgIUES/M0bnsyCknA6tzY8c9dLav3BowDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjMwMzAxMDExNzE2WhcNMjgwMjI4MDExNzE2WjBuMRgwFgYDVQQDDA9U
|
||||
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
|
||||
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo
|
||||
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvM2YfnzwBvd+B5Ro1
|
||||
z+LaCVYhxia9/hQwRhi5ag2HmeZZNgMNf4+bC75Nv+t3RW0lklbM9qJSBk03eEBG
|
||||
75Q33VPGy//WCJZgXlHV+rZ7ejzWtwh9Muhd60HFXhIsM3pwlfWpPo6bkJie9Na0
|
||||
wMsgg/8UxsNydhEZF6HFLdqY+zqGOjRRCduIyJcFhtrkjNUMIFAOSkHBaGJjmGrm
|
||||
OXigAnYAsaD1VWLOoblA0HlOs144KQ/5Shj74Ggk2pFo/YDN+i5hazHZo9hZnjmX
|
||||
G5BV3KDJD0k3Gn/qymhiLlzGsYW79P+BbsmE/M6jKIP2jxcDDdpek0Z6Lk0Cz/au
|
||||
02UPAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
|
||||
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
|
||||
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
|
||||
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
|
||||
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAJX6C/QMYF0F3IiK9P8tW2DKN8y9vCU20
|
||||
6Ws8u4bcO3AaiSmsdAJ6I1MyZkUg3dKijtnDbieY2P364IEp48TmI4k6UJwP4+/f
|
||||
i0NseOm3BmAJ3mBoNmuFul+61opKpeV67AYQuhbehVA4cDPqKb/hP0tEcb6nefIO
|
||||
mnys5GReLWLFV2XFR1h9QtsohPOEYlpBl6lmKHNoQZdAPtSHq2iVFLbuD7GMKoj7
|
||||
Br2puJEQgxla1AsNxAYjGttEIO9I30+L5av7SKesSGXvL6G5eOvFrZl0S4EsNVz4
|
||||
QeL4qmtFEKDi2eaxeyLuWe9TMI/IiI3ngekoDyTwdnUzadumbio+dg==
|
||||
-----END CERTIFICATE-----
|
||||
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIENzCCAx+gAwIBAgIUEvql9hcIt5W7UzeukVSU4twsqHswDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjMxMjE5MDUxNTA4WhcNMjgxMjE3MDUxNTA4WjCBkDETMBEGA1UEAwwK
|
||||
MTY1OTY2MjkzNjEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTwwOgYDVQQL
|
||||
DDPmiJDpg73ph5HniZvmrKPmrKPnm7jnhafkupLogZTnvZHljLvpmaLmnInpmZDl
|
||||
hazlj7gxCzAJBgNVBAYTAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZI
|
||||
hvcNAQEBBQADggEPADCCAQoCggEBAPCINl3HwUEM2CzerR5u4GbUnvRJDjVmaEbm
|
||||
qHlaYRUrrGDIF/Q63QEbcUh+PP+zZ0Grln7hGT5dwPj6e8jwmVvtEqO8mhBQzynH
|
||||
6MZUONVfxj7L5Pf/+vZtB/PPGKdupZ9tUuodqOrbLycE8xWmSUDPrKEZ9iOEYamz
|
||||
p0s9fPWwcZM8Vf4Gqx8d9ItnFJjVmF8aIJfsvcGNvKWD44JUzZItcsWz/srzxRAH
|
||||
2moGIM8eNf1UNm3k6q43dfoRbZryWmVIyw49xybAKzm5e4Q4z8jCwGoQWgs2tSF4
|
||||
uM0/SxK2j1XRGnVmwRzcdDq/rCPlbqynHXZyUh8Te1540HJKZK8CAwEAAaOBuTCB
|
||||
tjAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DCBmwYDVR0fBIGTMIGQMIGNoIGKoIGH
|
||||
hoGEaHR0cDovL2V2Y2EuaXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT0x
|
||||
QkQ0MjIwRTUwREJDMDRCMDZBRDM5NzU0OTg0NkMwMUMzRThFQkQyJnNnPUhBQ0M0
|
||||
NzFCNjU0MjJFMTJCMjdBOUQzM0E4N0FEMUNERjU5MjZFMTQwMzcxMA0GCSqGSIb3
|
||||
DQEBCwUAA4IBAQAe4CfX/m0Xz6aI/Studd5pbdb/M7cyTjTwYSoBUNKtEmBwQFCu
|
||||
CsFOEGuqmhq4ciMkooDWY/6mccgluZtdiYB8PQAIk1+IKBgpmhSuJP6yONecoit0
|
||||
JBWzFeSLkBxKkq6CfHhb9wW4EK0oPtgE6LjqLMj13fLy+Mxf4Eu4fgSlsdgGLpBt
|
||||
bXIPbL12bCcP5hJLGRoLbECyx9LaOe1D9RAxwcTx/i+8C1s3IajkkyZnoPasLMs6
|
||||
cdSIp20QSct0klMgpEobmV+Z59NMKAQC/pbaSRrT/PDHUTDAuwA7W+COALg6H26c
|
||||
MAGyeSTnwhc9WccmohKPgi3UcXh/Sn84QqSs
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDwiDZdx8FBDNgs
|
||||
3q0ebuBm1J70SQ41ZmhG5qh5WmEVK6xgyBf0Ot0BG3FIfjz/s2dBq5Z+4Rk+XcD4
|
||||
+nvI8Jlb7RKjvJoQUM8px+jGVDjVX8Y+y+T3//r2bQfzzxinbqWfbVLqHajq2y8n
|
||||
BPMVpklAz6yhGfYjhGGps6dLPXz1sHGTPFX+BqsfHfSLZxSY1ZhfGiCX7L3Bjbyl
|
||||
g+OCVM2SLXLFs/7K88UQB9pqBiDPHjX9VDZt5OquN3X6EW2a8lplSMsOPccmwCs5
|
||||
uXuEOM/IwsBqEFoLNrUheLjNP0sSto9V0Rp1ZsEc3HQ6v6wj5W6spx12clIfE3te
|
||||
eNBySmSvAgMBAAECggEBAOVndDqjLozFHFRHGGOjKgDJHsUr/BIwFpowmVQMP/V6
|
||||
DtDLZhU4ItpQew3B4JmbWIrIhSODupjBwC92bqLp3cpP5Gwnj+SpvbtCf57QatgO
|
||||
nTv9KObizE9FE8WTqhbeL7ZLBT5mhVlhLKqRTOpECy92IlYQNbIQKzk4MAFRpqGH
|
||||
CqSMtD0ng6DiMDxdQYLgIDCZIKamv0lF3rQymINQ6VZHpdlB0f3Gp/T/yWzn0nmJ
|
||||
5eOrBhzFKGpevsp00FmvFE7HSqnogC7a3ieLluhfRPyB4QZQjfMorEGKwS8i7I8U
|
||||
ZLA9FhtsaZpvOeNSZoVh3z0sblKUOvhXvL+jgRQK4PkCgYEA+M0QxM3VXst+deDr
|
||||
ZkpmhWdPUQykVdSbfOdR8thYDu30QdjKe/T0X75wcqKh+s2GPK2GZsgeU02+EWqv
|
||||
gVZMgFwGKFCBzDiCs9QwOTO+32OWP62yapFWNba1g4K7Un7MJRsJIj0u0nwjik68
|
||||
hec5KFYTOYttzk9oOLgXLFM6zm0CgYEA933lgvPITFykd2kGKg1v4oA52PPmq9LT
|
||||
2dvVkDpIxioaUUHPALwFLhHLT+w/RPwCfP9gqZAQQFAfpMiTezm+ULA54rLHF2Tj
|
||||
Lm0q3ko98sFW3Ltk1ehw8CdU0p5bii7a7AbuS6V36iTIrC53rhl7N+WL82uMw2w/
|
||||
a8Gz3fIl3gsCgYA+XsHeZC8iBWddS5YXXX1X4e8bRU0JCzQzWpXLh/qDO5mozBzu
|
||||
eBiuy8HKqwRqKA2HtoRjzbT0cx+7o//9L1IcN3V/s7bmKCBzzjSMknE99OwcaIG6
|
||||
f1aaPoRARIyLAKhSgPWINMhBEcejC1vtQWqttu441cAgIP3ighulC/RI/QKBgQDE
|
||||
lxKqdK8USTqzR4+H8+h+CNDqjsMalXuGwGLiEAoirur8xMODl9adg7D2KXkQeQYY
|
||||
+Fp2FmNyUrLwGAtehL2yJmm0s8IFyTPUew7kSCDxJbaz2377k4mymet86iFYoGNx
|
||||
vQeouyWHrfRhIQAcIU2JVyNWFoZX7TJrjBAuKtz9hQKBgGUFIyhQiPYRWDocvuSi
|
||||
McyzYov2AnNehn24vsXC3SCXT804KPOX8RY4he63zWMGaLfCmSq1fhsJnf2pvffK
|
||||
W+9ZXlIH6dwgQ9QyDNjKRVCGwTASsWOyqgn1Be0VDuuoXlREyGNQSn2RpvL1SMFH
|
||||
PW/ePgdfoFkzU5WFJFPnvlU2
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEFDCCAvygAwIBAgIUW1yKacyG0RJ/a2qgaqrxBTHu/pAwDQYJKoZIhvcNAQEL
|
||||
BQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT
|
||||
FFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg
|
||||
Q0EwHhcNMjMxMjE5MDUxNTA3WhcNMjgxMjE3MDUxNTA3WjBuMRgwFgYDVQQDDA9U
|
||||
ZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl
|
||||
bnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGEwJDTjERMA8GA1UEBwwIU2hlblpo
|
||||
ZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQClp0R6MR6NwEkqRJNF
|
||||
aD1INE0uHoRg1of0D8mTVwoWvADgt9gutpeJ1uTweAtrXkvu9NALxTNaG51tsZa8
|
||||
2fsJ00/Ry1IYUb6xG7kAuh0h4KLgWUUhoXDOKW0B1K/7g3AhCAylUzhD/ghD1Y8F
|
||||
hlMtw87oNzfTE51I/2sGZgnPX2IqIEOjxx1F8Ebzfh5shJGN40guMpBItsCWYe7s
|
||||
zj1zdyERL6zxQN2A7o2QvDeX1EsNIdwoEECv06tWjUEGJioFwb3OKBu5n9jJT+Og
|
||||
EcJFmRasLRQWsooutsDCO7y5wIKrCY9n52eZgk9QlHkYWyiwUqpnrrJ1DC+ueJei
|
||||
QptFAgMBAAGjgbkwgbYwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwgZsGA1UdHwSB
|
||||
kzCBkDCBjaCBiqCBh4aBhGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMv
|
||||
aXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4
|
||||
RUJEMiZzZz1IQUNDNDcxQjY1NDIyRTEyQjI3QTlEMzNBODdBRDFDREY1OTI2RTE0
|
||||
MDM3MTANBgkqhkiG9w0BAQsFAAOCAQEAhWwscSAE1OBR3AGBOuFHs3vFJ+y37z5/
|
||||
EoB9FwVu4zXP1dih101zl83iwIdPEHIR2skXcTjHRI2qdOvu7X5JmWOJP+51RGtX
|
||||
Y+aWXKfhRzRQOUlpNyltlgsGKzbIXLLBzQjMzBNv+n/HX4q9F0TV3SW4zTiMlhD8
|
||||
+bGGGwuIhziWpK9qvr3RPU1j+0bggHhIre+cNolnh1FepS4Gt964zhx6THtrS/jI
|
||||
I64UBBh6moBq7zB5QYloBhW464c7GCEEv5/AdcxGhAe+vuL/mkVRNsSRxVPIxPE6
|
||||
+qoIiNBmQvL/mL+4UKfX6b9h4wrUQUdQP3ljRdpL3a5YTMTUJuoJSQ==
|
||||
-----END CERTIFICATE-----
|
||||
@@ -0,0 +1,62 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
"vote-video-api/config"
|
||||
)
|
||||
|
||||
// CloseJsapiOrder 关闭jsapi支付订单
|
||||
func CloseJsapiOrder(outTradeNo string) error {
|
||||
client, err := createClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc := jsapi.JsapiApiService{Client: client}
|
||||
|
||||
req := jsapi.CloseOrderRequest{
|
||||
OutTradeNo: &outTradeNo,
|
||||
Mchid: core.String(config.C.Wechat.Pay1281030301.MchId),
|
||||
}
|
||||
|
||||
result, err := svc.CloseOrder(context.TODO(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 204 {
|
||||
return errors.New("关闭订单失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseAppOrder 关闭app支付订单
|
||||
func CloseAppOrder(outTradeNo string) error {
|
||||
client, err := createClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
|
||||
req := app.CloseOrderRequest{
|
||||
OutTradeNo: &outTradeNo,
|
||||
Mchid: core.String(config.C.Wechat.Pay1281030301.MchId),
|
||||
}
|
||||
|
||||
result, err := svc.CloseOrder(context.TODO(), req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 204 {
|
||||
return errors.New("关闭订单失败")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/auth/verifiers"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/downloader"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/notify"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
"vote-video-api/config"
|
||||
)
|
||||
|
||||
// PayParseNotify 支付回调通知的验签与解密
|
||||
func PayParseNotify(c *gin.Context) (notifyReq *notify.Request, t *payments.Transaction, err error) {
|
||||
mchId := config.C.Wechat.Pay1281030301.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1281030301.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1281030301.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := "extend/weChat/certs/" + config.C.Wechat.Pay1281030301.MchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("微信支付生成失败")
|
||||
}
|
||||
|
||||
// 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器
|
||||
err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(c, mchPrivateKey, mchCertificateSerialNumber, mchId, v3ApiSecret)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// 2. 获取商户号对应的微信支付平台证书访问器
|
||||
certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchId)
|
||||
// 3. 使用证书访问器初始化 `notify.Handler`
|
||||
handler, err := notify.NewRSANotifyHandler(v3ApiSecret, verifiers.NewSHA256WithRSAVerifier(certificateVisitor))
|
||||
|
||||
transaction := new(payments.Transaction)
|
||||
notifyReq, err = handler.ParseNotifyRequest(context.Background(), c.Request, transaction)
|
||||
// 如果验签未通过,或者解密失败
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return notifyReq, transaction, nil
|
||||
}
|
||||
|
||||
// RefundParseNotify 退款回调通知的验签与解密
|
||||
func RefundParseNotify(c *gin.Context) (notifyReq *notify.Request, t *refunddomestic.Refund, err error) {
|
||||
mchId := config.C.Wechat.Pay1281030301.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1281030301.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1281030301.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := "extend/weChat/certs/" + config.C.Wechat.Pay1281030301.MchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
if err != nil {
|
||||
return nil, nil, errors.New("微信支付生成失败")
|
||||
}
|
||||
|
||||
// 1. 使用 `RegisterDownloaderWithPrivateKey` 注册下载器
|
||||
err = downloader.MgrInstance().RegisterDownloaderWithPrivateKey(c, mchPrivateKey, mchCertificateSerialNumber, mchId, v3ApiSecret)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// 2. 获取商户号对应的微信支付平台证书访问器
|
||||
certificateVisitor := downloader.MgrInstance().GetCertificateVisitor(mchId)
|
||||
// 3. 使用证书访问器初始化 `notify.Handler`
|
||||
handler, err := notify.NewRSANotifyHandler(v3ApiSecret, verifiers.NewSHA256WithRSAVerifier(certificateVisitor))
|
||||
|
||||
refund := new(refunddomestic.Refund)
|
||||
notifyReq, err = handler.ParseNotifyRequest(context.Background(), c.Request, refund)
|
||||
// 如果验签未通过,或者解密失败
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return notifyReq, refund, nil
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
|
||||
)
|
||||
|
||||
/**
|
||||
JSAPI下单
|
||||
APP下单
|
||||
*/
|
||||
|
||||
// JsapiRequest 请求数据-JSAPI下单
|
||||
type JsapiRequest struct {
|
||||
AppId string `json:"appid" comment:"公众号ID"`
|
||||
MchId string `json:"mchid" comment:"直连商户号"`
|
||||
Description string `json:"description" comment:"商品描述"`
|
||||
OutTradeNo string `json:"out_trade_no" comment:"商户订单号"`
|
||||
NotifyUrl string `json:"notify_url" comment:"回调地址"`
|
||||
Amount JsapiRequestAmountRequest `json:"amount" comment:"订单金额"`
|
||||
Payer JsapiRequestPayerRequest `json:"payer" comment:"支付者"`
|
||||
}
|
||||
|
||||
// JsapiRequestAmountRequest 订单金额信息
|
||||
type JsapiRequestAmountRequest struct {
|
||||
Total int64 `json:"total" comment:"订单总金额"`
|
||||
Currency string `json:"currency" comment:"货币类型"`
|
||||
}
|
||||
|
||||
// JsapiRequestPayerRequest 支付者信息
|
||||
type JsapiRequestPayerRequest struct {
|
||||
OpenId string `json:"openid" comment:"openid"`
|
||||
}
|
||||
|
||||
// AppRequest 请求数据-APP下单
|
||||
type AppRequest struct {
|
||||
AppId string `json:"appid" comment:"公众号ID"`
|
||||
MchId string `json:"mchid" comment:"直连商户号"`
|
||||
Description string `json:"description" comment:"商品描述"`
|
||||
OutTradeNo string `json:"out_trade_no" comment:"商户订单号"`
|
||||
NotifyUrl string `json:"notify_url" comment:"回调地址"`
|
||||
Amount AppRequestAmountRequest `json:"amount" comment:"订单金额"`
|
||||
}
|
||||
|
||||
// AppRequestAmountRequest 订单金额信息
|
||||
type AppRequestAmountRequest struct {
|
||||
Total int64 `json:"total" comment:"订单总金额"`
|
||||
Currency string `json:"currency" comment:"货币类型"`
|
||||
}
|
||||
|
||||
// GetJsapiPrepay JSAPI下单-获取jsapi预支付交易会话
|
||||
func (r JsapiRequest) GetJsapiPrepay() (prepay *jsapi.PrepayWithRequestPaymentResponse, err error) {
|
||||
client, err := createClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
svc := jsapi.JsapiApiService{Client: client}
|
||||
// 得到prepay_id,以及调起支付所需的参数和签名
|
||||
PrepayRequest := jsapi.PrepayRequest{
|
||||
Appid: core.String(r.AppId),
|
||||
Mchid: core.String(r.MchId),
|
||||
Description: core.String(r.Description),
|
||||
OutTradeNo: core.String(r.OutTradeNo),
|
||||
NotifyUrl: core.String(r.NotifyUrl),
|
||||
Amount: &jsapi.Amount{
|
||||
Total: core.Int64(r.Amount.Total),
|
||||
Currency: core.String("CNY"),
|
||||
},
|
||||
Payer: &jsapi.Payer{
|
||||
Openid: core.String(r.Payer.OpenId),
|
||||
},
|
||||
}
|
||||
|
||||
resp, result, err := svc.PrepayWithRequestPayment(context.Background(),
|
||||
PrepayRequest,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 200 {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
if resp.PrepayId == nil {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// GetAppPrepay APP下单-获取app预支付交易会话
|
||||
func (r AppRequest) GetAppPrepay() (prepay *app.PrepayWithRequestPaymentResponse, err error) {
|
||||
client, err := createClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
// 得到prepay_id,以及调起支付所需的参数和签名
|
||||
|
||||
resp, result, err := svc.PrepayWithRequestPayment(context.Background(),
|
||||
app.PrepayRequest{
|
||||
Appid: core.String(r.AppId),
|
||||
Mchid: core.String(r.MchId),
|
||||
Description: core.String(r.Description),
|
||||
OutTradeNo: core.String(r.OutTradeNo),
|
||||
NotifyUrl: core.String(r.NotifyUrl),
|
||||
Amount: &app.Amount{
|
||||
Total: core.Int64(r.Amount.Total),
|
||||
Currency: core.String("CNY"),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 200 {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
if resp.PrepayId == nil {
|
||||
return nil, errors.New("发起支付失败")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/refunddomestic"
|
||||
)
|
||||
|
||||
type RefundRequest struct {
|
||||
TransactionId string `json:"transaction_id" comment:"微信订单号"`
|
||||
OutTradeNo string `json:"out_trade_no" comment:"商户订单号"`
|
||||
OutRefundNo string `json:"out_refund_no" comment:"退款订单号"`
|
||||
Reason string `json:"reason" comment:"退款原因"`
|
||||
RefundAmount int64 `json:"refund_amount" comment:"退款金额"`
|
||||
PaymentAmountTotal int64 `json:"payment_amount_total" comment:"支付金额"`
|
||||
NotifyUrl string `json:"notify_url" comment:"回调地址"`
|
||||
}
|
||||
|
||||
// Refund 退款
|
||||
func (r RefundRequest) Refund() (*refunddomestic.Refund, error) {
|
||||
client, err := createClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refundRequest := refunddomestic.CreateRequest{
|
||||
TransactionId: core.String(r.TransactionId),
|
||||
OutTradeNo: core.String(r.OutTradeNo),
|
||||
OutRefundNo: core.String(r.OutRefundNo),
|
||||
Reason: core.String(r.Reason),
|
||||
NotifyUrl: core.String(r.NotifyUrl),
|
||||
Amount: &refunddomestic.AmountReq{
|
||||
Currency: core.String("CNY"),
|
||||
Refund: core.Int64(r.RefundAmount),
|
||||
Total: core.Int64(r.PaymentAmountTotal),
|
||||
},
|
||||
}
|
||||
|
||||
svc := refunddomestic.RefundsApiService{Client: client}
|
||||
resp, _, err := svc.Create(context.Background(), refundRequest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp, nil
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GetUserInfoResponse 网页授权拉取用户信息返回值
|
||||
type GetUserInfoResponse struct {
|
||||
OpenId string `json:"openid" form:"openid" label:"openid"`
|
||||
Nickname string `json:"nickname" form:"nickname" label:"用户昵称"`
|
||||
Sex int `json:"sex" form:"sex" label:"性别"` // 用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
|
||||
Province string `json:"province" form:"province" label:"省份"`
|
||||
City string `json:"city" form:"city" label:"城市"`
|
||||
Country string `json:"country" form:"country" label:"国家"`
|
||||
HeadImgUrl string `json:"headimgurl" form:"headimgurl" label:"头像"`
|
||||
UnionId string `json:"unionid" form:"unionid" label:"unionid"`
|
||||
Errcode *int `json:"errcode" form:"errcode" label:"errcode"`
|
||||
Errmsg string `json:"errmsg" form:"errmsg" label:"errmsg"`
|
||||
}
|
||||
|
||||
// GetUserInfo 网页授权拉取用户信息
|
||||
func GetUserInfo(accessToken, openId string) (r *GetUserInfoResponse, err error) {
|
||||
if accessToken == "" {
|
||||
return nil, errors.New("授权失败")
|
||||
}
|
||||
|
||||
if openId == "" {
|
||||
return nil, errors.New("授权失败")
|
||||
}
|
||||
|
||||
// 拼接请求数据
|
||||
requestUrl := "https://api.weixin.qq.com/sns/userinfo?" +
|
||||
"access_token=" + accessToken +
|
||||
"&openid=" + openId +
|
||||
"&lang=zh_CN"
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := http.Get(requestUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response GetUserInfoResponse
|
||||
err = json.Unmarshal([]byte(respBody), &response)
|
||||
if err != nil {
|
||||
// json解析失败
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.Errcode != nil {
|
||||
if response.Errmsg != "" {
|
||||
return nil, errors.New(response.Errmsg)
|
||||
} else {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package weChat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"net/http"
|
||||
"vote-video-api/config"
|
||||
)
|
||||
|
||||
// GetWebAccessTokenResponse 获取网页授权access_token返回值
|
||||
type GetWebAccessTokenResponse struct {
|
||||
AccessToken string `json:"access_token" form:"access_token" label:"网页授权接口调用凭证"`
|
||||
ExpiresIn int `json:"expires_in" form:"expires_in" label:"access_token接口调用凭证超时时间"`
|
||||
RefreshToken string `json:"refresh_token" form:"refresh_token" label:"用户刷新access_token"`
|
||||
OpenId string `json:"openid" form:"openid" label:"openid"`
|
||||
Scope string `json:"scope" form:"scope" label:"scope"`
|
||||
UnionId string `json:"unionid" form:"unionid" label:"unionid"`
|
||||
Errcode *int `json:"errcode" form:"errcode" label:"errcode"`
|
||||
Errmsg string `json:"errmsg" form:"errmsg" label:"errmsg"`
|
||||
}
|
||||
|
||||
// GetWebAccessToken 获取网页授权access_token
|
||||
func GetWebAccessToken(code string) (r *GetWebAccessTokenResponse, err error) {
|
||||
// 拼接请求数据
|
||||
requestUrl := "https://api.weixin.qq.com/sns/oauth2/access_token?" +
|
||||
"appid=" + config.C.Wechat.AppId +
|
||||
"&secret=" + config.C.Wechat.AppSecret +
|
||||
"&code=" + code +
|
||||
"&grant_type=authorization_code"
|
||||
|
||||
// 发送GET请求
|
||||
resp, err := http.Get(requestUrl)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
|
||||
// 读取响应体
|
||||
respBody, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var response GetWebAccessTokenResponse
|
||||
err = json.Unmarshal([]byte(respBody), &response)
|
||||
if err != nil {
|
||||
// json解析失败
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if response.Errcode != nil {
|
||||
if response.Errmsg != "" {
|
||||
return nil, errors.New(response.Errmsg)
|
||||
} else {
|
||||
return nil, errors.New("请求失败")
|
||||
}
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
Reference in New Issue
Block a user