1 Star 0 Fork 0

wiztalk/wechatpay-go

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
Clone or Download
contribute
Sync branch
Cancel
Notice: Creating folder will generate an empty file .keep, because not support in Git
Loading...
README
Apache-2.0

微信支付 API v3 Go SDK

GoDoc huntr licence

微信支付 API v3 官方Go语言客户端代码库。

版本信息

版本号:v0.2.5

版本功能:

  1. 支持微信支付 API v3 请求签名与应答验签能力的 HTTP Client: core.Client,该 HTTP Client 在执行请求时将自动携带身份认证信息,并检查应答的微信支付签名。
  2. 微信支付平台证书下载库 core/downloader,提供手动下载器CertificateDownloader,以及自动下载管理器CertificateDownloaderMgr
  3. 微信支付回调通知处理库 core/notify,提供通知处理器Handler,可以对微信支付回调通知进行验签,然后对回调通知内容进行解密,并解析为特定的结构(如支付回调通知的Transaction),也可以选择解析为字典map[string]interface{}
  4. 微信支付各服务API对应的SDK,目前仅包含:
    • 微信核心支付4种常用支付接口(JSAPI支付, APP支付,H5支付,Native支付)的SDK。特别的,为【JSAPI支付】与【APP支付】提供了自动构建拉起支付所需签名的接口。
    • 微信支付4种文件上传接口的SDK
    • 微信支付证书下载接口的SDK
    • 微信支付境内退款接口的SDK
    • 更多API跟进中

兼容性: 本版本为测试版本,因为接口重命名/代码结构调整等原因,与之前版本存在不兼容的情况。

帮助我们改进SDK

为了向广大开发者提供更好的使用体验,微信支付诚挚邀请您将使用微信支付 API v3 SDK中的感受反馈给我们。 您的反馈将对我们改进SDK大有帮助,点击参与问卷调查

重大更新(Breaking Change)

版本 v0.2.2 中我们包含了一个重大更新内容:将现有接口SDK中的整型参数统一为int64。 这一行为的目的是规范SDK中对整型参数的实现,避免因为未来可能的int32 -> int64的字段升级导致大规模兼容性问题。

此次升级会导致 payments 下4个API接口的SDK的兼容性问题,建议开发者以如下方式对自己的代码进行更新。

SDK整型参数统一为int64代码修复步骤

1. 升级依赖
  1. 在你的模块目录下执行 go get -u github.com/wechatpay-apiv3/wechatpay-go@v0.2.5 升级依赖。
  2. (正常情况下该步骤会自动完成)修改模块 go.mod 文件中依赖的 github.com/wechatpay-apiv3/wechatpay-gov0.2.5版本。
2. 定位需要修改的代码

在项目根目录下执行go build ./...可以递归检查代码中的编译错误,即可快速定位到需要修改的代码。

3. 对请求构建代码进行更新

对于请求 payments 接口的数据,可以在设置参数时使用int64(xxx)进行类型转换。当然也可以将请求链路上的类型从int32更新为int64

req := jsapi.PrepayRequest{}
// 升级前
req.Amount = &jsapi.Amount{
	Currency: core.String("CNY"),
	Total:    &totalInt32,
}
// 升级后
totalInt64 := int64(totalInt32)
req.Amount = &jsapi.Amount{
	Currency: core.String("CNY"),
	Total:    &totalInt64,
}
4. 对应答处理代码进行更新

对于应答结果的处理,我们不建议将返回结果中的int64强制类型转换为int32,而是建议将后续处理链路中的类型从int32更新为int64。 这样变更可能会更复杂,但是安全性更好,避免因为数据溢出导致错误。

// 升级前
func GetTransactionTotal(resp *payments.Transaction) int32 {
	return *resp.Amount.Total
}
// 升级后
func GetTransactionTotal(resp *payments.Transaction) int64 {
	return *resp.Amount.Total
}
5. 更新你的测试用例代码并测试

如果你有针对 payments 编写测试用例,你可能需要对测试用例代码进行更新,并重新测试确保一切正常。

快速开始

安装

1、使用 Go Modules 管理你的项目(如果项目目录下存在go.mod文件的话说明你的项目已经使用 Go Modules 进行管理)

如果你的项目还不是使用 Go Modules 进行管理,在项目根目录下执行:

go mod init

2、添加依赖

go.mod 文件中加入对本SDK的依赖:

require (
    github.com/wechatpay-apiv3/wechatpay-go v0.2.5
)

并使用go mod tidy进行下载。

也可以直接在项目目录中执行:

go get -u github.com/wechatpay-apiv3/wechatpay-go@v0.2.5

来自动完成go.mod的修改与SDK的下载。

初始化 Client

为向微信支付 API 发送请求,需要初始化一个 core.Client 实例。

package main

import (
	"context"
	"crypto/rsa"
	"log"
	"net/http"

	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
)

func main() {
	// 示例参数,实际使用时请自行初始化
	var (
		mchID                      string              // 商户号
		mchCertificateSerialNumber string              // 商户证书序列号
		mchPrivateKey              *rsa.PrivateKey     // 商户私钥
		mchAPIv3Key                string              // 商户APIv3密钥
		customHTTPClient           *http.Client        // 可选,自定义客户端实例
	)

	ctx := context.Background()
	opts := []core.ClientOption{
		// 一次性设置 签名/验签/敏感字段加解密,并注册 平台证书下载器,自动定时获取最新的平台证书
		option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
		// 设置自定义 HTTPClient 实例,不设置时默认使用 http.Client{},并设置超时时间为 30s
		option.WithHTTPClient(customHTTPClient),
	}
	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		log.Printf("new wechat pay client err:%s", err)
		return
	}
	// 接下来使用 client 进行请求发送
	_ = client
}

使用以上方法,可以快速构建一个集成了签名/验签的Client,除此以外,还会自动初始化全局默认的平台证书下载管理器downloader.MgrInstance()提供平台证书。 每24小时更新一次平台证书,保证验签所使用的证书更新。

如果你希望直接使用本地的平台证书,也可以使用如下初始化方法

func main() {
	// 示例参数,实际使用时请自行初始化
	var (
		mchID                      string              // 商户号
		mchCertificateSerialNumber string              // 商户证书序列号
		mchPrivateKey              *rsa.PrivateKey     // 商户私钥
		wechatPayCertList          []*x509.Certificate // 平台证书列表
		customHTTPClient           *http.Client        // 可选,自定义客户端实例
	)

	ctx := context.Background()
	opts := []core.ClientOption{
		// 一次性设置 签名/验签/敏感字段加解密,使用本地提供的平台证书列表
		option.WithWechatPayAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, wechatPayCertList),
		// 设置自定义 HTTPClient 实例,不设置时默认使用 http.Client{},并设置超时时间为 30s
		option.WithHTTPClient(customHTTPClient),
	}
	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		log.Printf("new wechat pay client err:%s", err)
		return
	}
	// 接下来使用 client 进行请求发送
	_ = client
}

core.Client初始化完成后,可以在多个goroutine中并发使用。

名词解释

  • 商户API证书,是用来证实商户身份的。证书中包含商户号、证书序列号、证书有效期等信息,由证书授权机构(Certificate Authority ,简称CA)签发,以防证书被伪造或篡改。如何获取请见 商户API证书
  • 商户API私钥。商户申请商户API证书时,会生成商户私钥,并保存在本地证书文件夹的文件apiclient_key.pem中。注:不要把私钥文件暴露在公共场合,如上传到Github,写在客户端代码等。
  • 微信支付平台证书。平台证书是指由微信支付负责申请的,包含微信支付平台标识、公钥信息的证书。商户可以使用平台证书中的公钥进行应答签名的验证。获取平台证书需通过 获取平台证书列表 接口下载。
  • 证书序列号。每个证书都有一个由CA颁发的唯一编号,即证书序列号。如何查看证书序列号请看 这里
  • 微信支付APIv3密钥,是在回调通知和平台证书下载接口中,为加强数据安全,对关键信息进行AES-256-GCM加密时使用的对称加密密钥。

使用服务接口 SDK

为了方便开发者快速上手,我们给各服务分别生成了相应的示例代码api_xx_example_test.go。例如 JSAPI 支付的示例代码就位于services/payments/jsapi/api_jsapi_example_test.go。开发者可以按需查阅。

以下我们以常用的接口为例,说明如何使用服务接口 SDK。

JSAPI下单 为例

import (
	"log"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
)

func JsapiPrepay() error {
	// 请自行初始化 client
	var client *core.Client
	
	svc := jsapi.JsapiApiService{Client: client}
	// 得到prepay_id,以及调起支付所需的参数和签名
	resp, result, err := svc.PrepayWithRequestPayment(ctx,
		jsapi.PrepayRequest{
			Appid:       core.String("wxd678efh567hg6787"),
			Mchid:       core.String("1900009191"),
			Description: core.String("Image形象店-深圳腾大-QQ公仔"),
			OutTradeNo:  core.String("1217752501201407033233368018"),
			Attach:      core.String("自定义数据说明"),
			NotifyUrl:   core.String("https://www.weixin.qq.com/wxpay/pay.php"),
			Amount: &jsapi.Amount{
				Total: core.Int32(100),
			},
			Payer: &jsapi.Payer{
				Openid: core.String("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o"),
			},
		},
	)
	
	if err == nil {
		log.Println(resp)
	} else {
		log.Println(err)
		return err
	}
}

查询订单 为例

import (
	"log"
	"github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi"
)

func QueryOrder() error {
	// 请自行初始化 client
	var client *core.Client
	svc := jsapi.JsapiApiService{Client: client}
	
	resp, result, err := svc.QueryOrderById(ctx,
		jsapi.QueryOrderByIdRequest{
			TransactionId: core.String("4200000985202103031441826014"),
			Mchid:         core.String("1900009191"),
		},
	)
	
	if err == nil {
		log.Println(resp)
	} else {
		log.Println(err)
		return err
	}
}

图片上传API 为例:

import (
	"os"
	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/consts"
	"github.com/wechatpay-apiv3/wechatpay-go/services/fileuploader"
)

func UploadImage() error {
	// 请自行初始化 client
	var client *core.Client
	
	file, err := os.Open("resource/demo.jpg")
	defer file.Close()
	if err != nil {
		return err
	}
	
	svc := fileuploader.ImageUploader{Client: client}
	resp, result, err := svc.Upload(ctx, file, "demo.jpg", consts.ImageJPG)
	// 处理 resp 
}

发送 HTTP 请求

如果你需要使用的 SDK 尚未提供,你可以使用core.ClientGETPOST等方法发送 HTTP 请求,而不用关心签名验签等逻辑。

下载微信支付平台证书 为例:

var (
	result *core.APIResult
	err error
)
result, err = client.Get(ctx, "https://api.mch.weixin.qq.com/v3/certificates")
// 处理 result.Response

使用 core.Client 发送 HTTP 请求后会得到一个 core.APIResult 实例,其中包含了当次请求的请求报文 *http.Request 以及应答报文 *http.Response

错误处理

以下情况,SDK 发送请求会返回 error

  • HTTP 网络错误,如应答接收超时或网络连接失败
  • 客户端失败,如生成签名失败
  • 服务器端返回了 2xx HTTP 状态码
  • 应答签名验证失败

为了方便使用,我们将服务器返回的 4xx5xx 错误,转换成了APIError。开发者可以参考以下的代码进行错误处理。

result, err := client.Get(ctx, "https://api.mch.weixin.qq.com/v3/certificates")
if err != nil {
	if core.IsAPIError(err, "INVALID_REQUEST") { 
		// 处理无效请求 
	}
	// 处理的其他错误
}

目录介绍

github.com/wechatpay-apiv3/wechatpay-go
├── core       // 本代码库核心功能
├── services   // 微信支付各服务API对应的SDK,目前只包含部分API,更多服务跟进中
├── docs       // 以上微信支付各服务API对应的SDK的说明文档
├── utils      // 各种常用工具函数
└── README.md  // 本文档

敏感信息加解密

为了保证通信过程中敏感信息字段(如用户的住址、银行卡号、手机号码等)的机密性,微信支付 API v3 要求商户对上送的敏感信息字段进行加密。 与之相对应,微信支付会对下行的敏感信息字段进行加密,商户需解密后方能得到原文。 详见这里

加解密算法工具包

工具包 github.com/wechatpay-apiv3/wechatpay-go/utils 中提供了加解密所需要的函数,可以使用这些方法手动对敏感信息字段进行加解密

package utils

// EncryptOAEPWithPublicKey 使用公钥进行加密
func EncryptOAEPWithPublicKey(message string, publicKey *rsa.PublicKey) (ciphertext string, err error)
// EncryptOAEPWithCertificate 先解析出证书中的公钥,然后使用公钥进行加密
func EncryptOAEPWithCertificate(message string, certificate *x509.Certificate) (ciphertext string, err error)

// DecryptOAEP 使用私钥进行解密
func DecryptOAEP(ciphertext string, privateKey *rsa.PrivateKey) (message string, err error)

获取平台证书

如果你使用option.WithWechatPayAutoAuthCipher初始化core.Client,SDK 会自动在默认的证书下载管理器中注册对应商户的证书下载和自动更新任务。 它除了会为core.Client中的验签器提供平台证书外,你可以直接使用mgr.GetCertificatemgr.GetCertificateVisitor等方法直接获取到证书,用于敏感字段的加密。

设置 Wechatpay-Serial 请求头

对请求参数进行加密后,需要在请求头中添加 Wechatpay-Serial 参数,用于传递加密所使用的微信支付平台证书序列号。

目前 core.ClientGet/Post/Put/Patch/Delete/Upload 方法只能传递最简单的内容,并不支持设置 HTTPHeader。 你可以使用 Request 方法来传输自定义 HTTPHeader。

[建设中] 服务 SDK 自动加解密

目前我们已经完成了敏感字段自动加解密工具的开发,你可以使用WithWechatPayAuthCipher/WithWechatPayAutoAuthCipher/WithCipher等选项为 core.Client 设置加解密器。 但是比较遗憾的是,加解密器的正确运作依赖于我们在接口请求/应答结构所进行的Tag标记,也就是说只有我们提供了SDK的服务才能享受到自动加解密。 而目前我们所提供了SDK的服务接口均不存在需要加解密的字段,故而暂时这个能力还无法为大家提供服务。如果开发者需要访问存在敏感字段的接口,目前还是需要手动进行加解密。 我们会尽快上线更多服务接口的SDK,让自动加解密发挥它的价值。

回调通知验签与解密

core/notify 中提供了回调通知处理器 Handler,提供回调通知验签与解密功能。Handler 需要使用验签器 Verifier 和 商户APIv3密钥进行初始化。

mchAPIv3Key := "<your api v3 key>"
verifier := verifiers.NewSHA256WithRSAVerifier(core.NewCertificateMapWithList([]*x509.Certificate{wechatPayCert})) 

handler := NewNotifyHandler(mchAPIv3Key, verifier)

初始化完成后即可调用handler.ParseNotifyRequest方法进行回调通知的验签及解密。

使用平台证书下载管理器初始化 notify.Handler

如果你已经知道如何在创建 client 的时候使用平台证书下载管理器自动更新平台证书,你可以在回调处理中也享受管理器提供了平台证书自动更新能力。 为了你能正确使用平台证书管理器,请确保你已经阅读并理解在更多地方使用平台证书下载管理器的说明。

以下是使用平台证书下载管理器初始化 notify.Handler 的示例代码

var (
	mchID                      string              // 商户号
	mchCertificateSerialNumber string              // 商户证书序列号
	mchPrivateKey              *rsa.PrivateKey     // 商户私钥
	mchAPIv3Key                string              // 商户APIv3密钥
)

func Example_a() {
	ctx := context.Background()
	client, err := core.NewClient(ctx, option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key))
	if err != nil {
		return
	}
	
	// 由于已经使用 WithWechatPayAutoAuthCipher 在 downloader.MgrInstance() 中注册了商户的下载器,则下面可以直接使用该下载管理器获取证书
	certVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)
	handler := notify.NewNotifyHandler(mchAPIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
}

func Example_b() {
	// 这是一个单纯的回调处理进程,没有使用 WithWechatPayAutoAuthCipher 创建商户的 client,此时则需要手动注册下载器
	ctx := context.Background()
	err := downloader.MgrInstance().RegisterDownloaderWithPrivateKey(ctx, mchPrivateKey, mchCertificateSerialNumber, mchID, mchAPIV3Key)
	if err != nil {
		return	
	}
	
	// 注册完成,使用下载管理器获取证书
	certVisitor := downloader.MgrInstance().GetCertificateVisitor(mchID)
	handler := notify.NewNotifyHandler(mchAPIv3Key, verifiers.NewSHA256WithRSAVerifier(certVisitor))
}

自定义签名生成器与验证器

当默认的本地签名和验签方式不适合你的系统时,你可以通过实现Signer或者Verifier来定制签名和验签。 比如,你可以把商户私钥集中存储,业务系统通过远程调用进行签名,你可以这样做。

// 签名器
type CustomSigner struct {
}

func (s *CustomSigner) Sign(ctx context.Context, message string) (*auth.SignatureResult, error) {
    // TODO: 远程调用获取签名信息
    return &auth.SignatureResult{MchID: "xxx", MchCertificateSerialNo: "xxx", Signature: "xxx"}, nil
}

// 校验器
type CustomVerifier struct {
}

func (v *CustomVerifier) Verify(ctx context.Context, serial, message, signature string) error {
    // TODO: 远程调用验签
    return nil
}

当你需要使用自定的签名器和校验器时,你可以这样来创建客户端

package core_test

import (
	"context"

	"path/to/your/custom_signer"
	"path/to/your/custom_verifier"

	"github.com/wechatpay-apiv3/wechatpay-go/core"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/credentials"
	"github.com/wechatpay-apiv3/wechatpay-go/core/auth/validators"
	"github.com/wechatpay-apiv3/wechatpay-go/core/option"
)

func NewCustomClient(ctx context.Context, mchID string) (*core.Client, error) {
	signer := &custom_signer.CustomSigner{
		// ... 
	}
	verifier := &custom_verifier.CustomVerifier{
		// ...
	}

	opts := []core.ClientOption{
		option.WithSigner(signer),
		option.WithVerifier(verifier),
	}

	return core.NewClient(ctx, opts...)
}

常见问题

如何下载平台证书

现在本 SDK 已经提供了命令行工具供开发者使用。

首先使用 go 指令下载命令行工具

go get -u github.com/wechatpay-apiv3/wechatpay-go/cmd/wechatpay_download_certs@v0.2.5

然后执行 wechatpay_download_certs 即可下载平台证书到当前目录

wechatpay_download_certs -m <mchID> -p <mchPrivateKeyPath> -s <mchSerialNo> -k <mchAPIv3Key>

完整参数列表可运行 wechatpay_download_certs -h 进行查看。

如何在更多地方使用平台证书下载管理器

注意: 如果你想使用 downloader.MgrInstance().GetCertificatedownloader.MgrInstance().GetCertificateVisitor 来获取某个商户mchID的平台证书(比如用于回调通知验签), 请确保你在该进程中使用过 option.WithWechatPayAutoAuthCipher 创建该商户的 client。 这是因为平台证书下载管理器必须使用商户信息注册下载器之后才能提供对应商户的平台证书。

如果你并不需要创建该商户的 client,请使用 downloader.MgrInstance().RegisterDownloaderWithPrivateKey 手动注册下载器。

option.WithWechatPayAutoAuthCipherdownloader.MgrInstance().RegisterDownloaderWithPrivateKey 只需要在进程中调用过一次即可,多次调用无实际意义。 如果二者都没有调用过,则查询该商户的平台证书时结果均为空。

如果你希望了解更多,并自行对平台证书下载管理器的生命周期进行管理,可以自行阅读 core/downloader 的代码。

如何下载账单

账单下载API 分成了两个步骤:

  1. /v3/bill/tradebill 获取账单下载链接和账单摘要
  2. /v3/billdownload/file 账单文件下载,请求需签名但应答不签名

其中第二步的应答中不包含应答数字签名,无法进行验签,应使用WithoutValidator()跳过应答签名的校验。

opts := []core.ClientOption{
	option.WithMerchantCredential(mchID, mchCertificateSerialNumber, privateKey),
	option.WithoutValidator(),
}

client, err := core.NewClient(ctx, opts...)

注意:第一步中应正常对应答签名进行验证

注意:开发者在下载文件之后,应使用第一步获取的账单摘要校验文件的完整性

如何查看 HTTP 请求的 Request 信息

不论是使用 Client 的 HTTP 方法(Get/Post/Put/Delete等)直接发送 HTTP 请求,还是使用服务API对应的SDK发起请求,均会返回 *core.APIResult 结构。 该结构中包含了本次发起 HTTP 请求的 http.Request 对象和微信支付应答的 http.Response 对象。

var (
	request *http.Request
	response *http.Response
)
result, err = client.Get(ctx, "")

request = result.Request
response = result.Response 

证书和回调解密需要的AesGcm解密在哪里?

请参考 aes.goaes_test.go

如何参与开发

我们欢迎来自社区的开发者贡献你们的想法和代码。请你在提交 PR 之前,先提一个对应的 issue 说明以下内容:

  • 背景(如,遇到的问题)和目的
  • 着重说明你的想法
  • 通过代码或者其他方式,简要的说明是如何实现的,或者它会是如何使用
  • 是否影响现有的接口

#35 是一个很好的参考。

测试

开发者提交的代码,应能通过我们所有的测试用例。

我们在单元测试中使用了gomonkeyrequire,测试前请确认相关的依赖。你可以使用以下命令获取所有的依赖。

go get -t -v

由于gomonkey的原因,在执行测试用例时需要携带参数-gcflags=all=-l。你可以使用以下命令发起测试。

go test -gcflags=all=-l ./...

联系我们

如果你发现了BUG或者有任何疑问、建议,欢迎通过 issue 进行反馈

也欢迎访问我们的开发者社区

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

No description expand collapse
Go
Apache-2.0
Cancel

Releases

No release

Contributors

All

Activities

can not load any more
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ariallyp/wechatpay-go.git
git@gitee.com:ariallyp/wechatpay-go.git
ariallyp
wechatpay-go
wechatpay-go
main

Search