wx

package module
v0.0.0-...-f2140e9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2023 License: Apache-2.0 Imports: 24 Imported by: 0

README

goclub/wechat

微信SDK

  1. 包含微信接口最佳实践,避免采坑背锅
  2. 接口友好,返回每个请求的 http Request/Response
  3. 类型安全,避免出现空指针panic

快速查找

如果你的编辑器有快速跳转功能 只需要在 wx.Index** 或者 index.go 文件中通过快速跳转到对应接口

比如打开 index.go 搜索 /connect/oauth2/authorize 然后右键变量 IndexConnectOauth2Authorize 选择类似查找用法的菜单即可跳转到对应函数

中控服务器

微信调用JSSDK或者小程序解密手机号都需要 access_token 和 ticket 微信要求自己实现中控服务器获取 access_token 和 ticket 我封装了中控服务端 https://github.com/goclub/wx-api-center-control 并在 goclub/wechat 这个项目提供了中控客户端.

作用 代码 文档
初始化 wx.NewAPICenterControl() goclub
获取 ticket wx.APICenterControlClient{}.Ticket() 官方
获取 access token wx.APICenterControlClient{}.AccessToken() 官方

公众号

公众号常用的有用户授权登录,官方没有SDK.我提供了一些方法来减少自己封装的工作量.并且提醒你处理类似快照用户的坑.

作用 代码 文档
初始化 wx.NewSnsClient()
第一步:用户同意授权,获取code wx.SnsClient{}.Oauth2Authorize() 官方
第二步:通过code换取网页授权access_token wx.SnsClient{}.Oauth2AccessToken() 官方
快照用户提醒页面 snapshot_user_page.html 官方
第三步:刷新access_token(如果需要) 未实现 官方
第四步:拉取用户信息(需scope为 snsapi_userinfo) wx.SnsClient{}.UserInfo() 官方
小程序登录 wx.SnsClient{}.Jscode2session() 官方

支付v3

微信支付3.0有官方SDK wechatpay-apiv3/wechatpay-go

官方代码中大量使用了 *string *int64,导致发送请求有点麻烦需要写 Appid: core.String("wxd678efh567hg6787") 而不是 Appid : "wxd678efh567hg6787

业务错误和网络错误都包含在err中,排查问题繁琐.

// 官方用法
resp, result, err := svc.PrepayWithRequestPayment(ctx, jsapi.PrepayRequest{
    Appid:       core.String("wxd678efh567hg6787"),
    Mchid:       core.String("1900009191"),
    // ...
},)
if err != nil {
var coreApiError *core.APIError
    if xerr.As(err, &coreApiError) {
        // 根据 coreApiError 错误进行记录等处理
        return
    }
    return
}
// 响应的 resp.PrepayId 类型是 *string
// 在 resp.PrepayId 是 nil 时
// 使用 id := *apiResp.PrepayId 会出现panic 空指针错误
// 坑坑坑
// goclub/wechat 封装后的方法
resp, httpResult, apiError, err := client.TransactionsJSAPI(ctx, wx.V3TransactionsJSAPIRequest{
    // 不需要 core.String
    Appid:       "wxd678efh567hg6787",
    Mchid:       "1900009191",
    // ...
})
if err != nil {
    return
}
if apiError != nil {
    // 接口错误单独处理记录
    log.Printf("接口错误:\n", apiError.Error())
    log.Print("http:\n",httpResult.DumpRequestResponseString(true))
    return apiError
}
// 不需要 *resp.PrepayId 避免空指针错误
id := resp.PrepayId
log.Print(id)
作用 代码 文档
初始化 wx.NewV3PayClient() 官方
官方Client wx.V3PayClient{}.Client
官方Handler wx.V3PayClient{}.Handler
JSAPI下单 wx.V3PayClient{}.TransactionsJSAPI() 官方
转账到零钱 wx.V3PayClient{}.TransferBatches() 官方

如何开发本项目

微信接口非常多,我只会把经过大量实践没有坑的接口封装出来并在实例中写上最佳实践. goclub/wechat 中没有的接口你可以先在自己项目中二次封装. 参考本项目的函数实现和使用本项目提供的一些工具函数能更快封装出接口友好的SDK 经过大量实践后提交 PR 或 直接在issues 贴出代码.我会根据你的代码加上功能.

封装参考代码:

  1. 公众号: 用户信息
  2. 微信支付: JS下单

Documentation

Index

Examples

Constants

View Source
const IndexCgiBinToken = "/cgi-bin/token"
View Source
const IndexCgiTicketGetTicket = "/cgi-bin/ticket/getticket"
View Source
const IndexConnectOauth2Authorize = "/connect/oauth2/authorize"
View Source
const IndexSnsJscode2session = "/sns/jscode2session"
View Source
const IndexSnsOauth2Access_token = "/sns/oauth2/access_token"
View Source
const IndexSnsUserInfo = "/sns/userinfo"
View Source
const IndexV3PayTransactionJSAPI = "/v3/pay/transactions/jsapi"
View Source
const IndexV3TransferBatches = "/v3/transfer/batches"

Variables

This section is empty.

Functions

func AbsURL

func AbsURL(r *http.Request) (url string)

func AsV3PayApiError

func AsV3PayApiError(err error, apiError *V3PayApiError) (is bool)

func EncodeSign

func EncodeSign(values url.Values, apikey string) string

func I642P

func I642P(i int64) *int64

func P2S

func P2S(p *string) string

func P2T

func P2T(t *time.Time) time.Time

func S2P

func S2P(s string) *string

func UUID32

func UUID32() string

Types

type APICenterControlAccessTokenReply

type APICenterControlAccessTokenReply struct {
	AccessToken string
}

type APICenterControlClient

type APICenterControlClient struct {
	Cache Cacher
	// contains filtered or unexported fields
}

APICenterControlClient 微信中控服务客户端 https://github.com/goclub/wx-api-center-control

func NewAPICenterControlClient

func NewAPICenterControlClient(config APICenterControlConfig) (client *APICenterControlClient, err error)

NewAPICenterControlClient 初始化微信中控服务客户端

Example
package main

import (
	"context"
	wx "github.com/goclub/wechat"
	"log"
)

func main() {
	err := func(ctx context.Context) (err error) {
		config := wx.APICenterControlConfig{
			Domain: "使用 https://github.com/goclub/wx-api-center-control 部署的中控服务器域名",
			SK:     "**",
		}
		var client *wx.APICenterControlClient
		if client, err = wx.NewAPICenterControlClient(config); err != nil {
			return
		}
		appid := "wx********"
		log.Print(client.Ticket(ctx, appid, "jsapi"))
		log.Print(client.AccessToken(ctx, appid))
		return
	}(context.Background())
	log.Printf("%+v", err)
}
Output:

func (APICenterControlClient) AccessToken

func (client APICenterControlClient) AccessToken(ctx context.Context, appid string) (reply APICenterControlAccessTokenReply, err error)

AccessToken 获取access_token https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。

func (APICenterControlClient) Ticket

func (client APICenterControlClient) Ticket(ctx context.Context, appid string, ticketType string) (reply APICenterControlTicketReply, err error)

Ticket https://developers.weixin.qq.com/doc/offiaccount/WeChat_Invoice/Nontax_Bill/API_list.html#2.1 ticket用于加强安全性。ticket的有效期目前为2个小时,需定时刷新。建议公众号开发者使用中控服务器统一获取和刷新ticket。

type APICenterControlConfig

type APICenterControlConfig struct {
	Domain string
	SK     string
	Cache  Cacher
}

type APICenterControlTicketReply

type APICenterControlTicketReply struct {
	Ticket string
}

type Cacher

type Cacher interface {
	Get(ctx context.Context, key string) (value string, has bool, err error)
	Set(ctx context.Context, key string, value string, expire time.Duration) (err error)
}

type SnsAPIError

type SnsAPIError struct {
	Errcode int64  `json:"errcode"`
	Errmsg  string `json:"errmsg"`
}

func (*SnsAPIError) Error

func (e *SnsAPIError) Error() string

func (SnsAPIError) Struct

func (e SnsAPIError) Struct() SnsAPIError

type SnsClient

type SnsClient struct {
	// contains filtered or unexported fields
}

func NewSnsClient

func NewSnsClient(config SnsConfig) (client *SnsClient, err error)

func (SnsClient) CoreSend

func (dep SnsClient) CoreSend(
	ctx context.Context, fnName string,
	method xhttp.Method, domain string, path string,
	request xhttp.SendRequest,
	resp interface {
		Error() string
		Struct() SnsAPIError
	},
) (httpResult xhttp.HttpResult, apiError *SnsAPIError, err error)

func (SnsClient) Jscode2session

func (dep SnsClient) Jscode2session(ctx context.Context, req SnsJscode2sessionRequest) (reply SnsJscode2sessionReply, httpResult xhttp.HttpResult, apiError *SnsAPIError, err error)

Jscode2session 小程序登录 code2Session https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html 登录凭证校验。通过 wx.login 接口获得临时登录凭证 code 后传到开发者服务器调用此接口完成登录流程。更多使用方法详见小程序登录。

Example
err := func(ctx context.Context) (err error) {

	var client *wx.SnsClient
	if client, err = NewSnsClient(); err != nil {
		return
	}
	var apiError *wx.SnsAPIError
	var httpResult xhttp.HttpResult
	var reply wx.SnsJscode2sessionReply
	if reply, httpResult, apiError, err = client.Jscode2session(ctx, wx.SnsJscode2sessionRequest{
		Code:   "",
		Appid:  "",
		Secret: "",
	}); err != nil {
		return
	}
	if apiError != nil {
		log.Print("接口错误:\n", apiError.Error())
		log.Print("http:\n", httpResult.DumpRequestResponseString(true))
		return apiError
	}
	// Unionid 绑定了微信开放平台才会有
	// reply.Unionid
	xjson.PrintIndent("reply", reply)
	return
}(context.Background())
log.Printf("%+v", err)
Output:

func (SnsClient) Oauth2AccessToken

func (dep SnsClient) Oauth2AccessToken(ctx context.Context, req SnsOauth2AccessTokenRequest) (reply SnsOAuth2AccessTokenReply, httpResult xhttp.HttpResult, apiError *SnsAPIError, err error)

Oauth2AccessToken 第二步:通过code换取网页授权access_token https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#1

Example
err := func(ctx context.Context) (err error) {

	var client *wx.SnsClient
	if client, err = NewSnsClient(); err != nil {
		return
	}
	var apiError *wx.SnsAPIError
	var httpResult xhttp.HttpResult
	var reply wx.SnsOAuth2AccessTokenReply
	if reply, httpResult, apiError, err = client.Oauth2AccessToken(ctx, wx.SnsOauth2AccessTokenRequest{
		Domain: "",
		Code:   "",
		Appid:  "",
		Secret: "",
	}); err != nil {
		return
	}
	if apiError != nil {
		log.Print("接口错误:\n", apiError.Error())
		log.Print("http:\n", httpResult.DumpRequestResponseString(true))
		return apiError
	}
	// 微信快照用户不要走登录的逻辑
	// 因为让快照用户登录可能会出现串号(A与B使用的是同一个快照用户)并且都是假用户获取user info 可能会微信报错
	if reply.IsSnapshotUser == 1 {
		return xerr.New("在这里给用户渲染 本项目下的 snapshot_user_page.html 文件")
	}
	xjson.PrintIndent("reply", reply)
	return
}(context.Background())
log.Printf("%+v", err)
Output:

func (SnsClient) Oauth2Authorize

func (dep SnsClient) Oauth2Authorize(req SnsOauth2AuthorizeRequest) (redirectURL string, err error)

Oauth2Authorize 第一步:用户同意授权,获取code https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html#0

func (SnsClient) UserInfo

func (dep SnsClient) UserInfo(ctx context.Context, req SnsUserInfoRequest) (reply SnsUserInfoReply, httpResult xhttp.HttpResult, apiError *SnsAPIError, err error)

UserInfo 第四步:拉取用户信息(需scope为 snsapi_userinfo)

Example
err := func(ctx context.Context) (err error) {

	var client *wx.SnsClient
	if client, err = NewSnsClient(); err != nil {
		return
	}

	var apiError *wx.SnsAPIError
	var httpResult xhttp.HttpResult
	var reply wx.SnsUserInfoReply
	if reply, httpResult, apiError, err = client.UserInfo(ctx, wx.SnsUserInfoRequest{
		// 通过 client.Oauth2AccessToken(code) 获取 token
		AccessToken: "xxx",
		// 通过 client.Oauth2AccessToken(code) 获取 openid
		OpenID: "***",
		Lang:   "zh_CN",
	}); err != nil {
		return
	}
	if apiError != nil {
		log.Print("接口错误:\n", apiError.Error())
		log.Print("http:\n", httpResult.DumpRequestResponseString(true))
		return apiError
	}
	// 实践
	// 只有在用户将公众号绑定到微信开放平台帐号后,才会出现 UnionID 该字段。
	// https://open.weixin.qq.com/ 注意是开放平台不是公众平台
	// reply.UnionID
	// 微信公众平台用户信息相关接口调整公告官方: 公众号用户信息获取接口:不再返回用户性别及地区信息;
	// https://developers.weixin.qq.com/community/develop/doc/00028edbe3c58081e7cc834705b801

	xjson.PrintIndent("reply", reply)
	return
}(context.Background())
log.Printf("%+v", err)
Output:

type SnsConfig

type SnsConfig struct {
	Domain SnsConfigDomain
}

type SnsConfigDomain

type SnsConfigDomain struct {
	OpenWeixin string `default:"https://open.weixin.qq.com"`
	ApiWeixin  string `default:"https://api.weixin.qq.com"`
}

type SnsJscode2sessionReply

type SnsJscode2sessionReply struct {
	Openid     string `json:"openid"`
	SessionKey string `json:"session_key"`
	// 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回,详见 UnionID 机制说明。
	// https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/union-id.html
	Unionid string `json:"unionid" note:"绑定了微信开放平台才会有"`
}

type SnsJscode2sessionRequest

type SnsJscode2sessionRequest struct {
	Code   string
	Appid  string
	Secret string
}

type SnsOAuth2AccessTokenReply

type SnsOAuth2AccessTokenReply struct {
	AccessToken  string `json:"access_token"`
	ExpiresIn    int64  `json:"expires_in"`
	Openid       string `json:"openid"`
	RefreshToken string `json:"refresh_token"`
	Scope        string `json:"scope"`
	// 注意!快照用户可能会导致串号,请参考一下链接
	// https://developers.weixin.qq.com/community/minihome/doc/000c2c34068880629ced91a2f56001
	// https://developers.weixin.qq.com/community/minihome/doc/0008ee0584489030956ea3bba5ec00?source=indexmixflow
	IsSnapshotUser int `` /* 133-byte string literal not displayed */
}

type SnsOauth2AccessTokenRequest

type SnsOauth2AccessTokenRequest struct {
	Domain string
	Code   string
	Appid  string
	Secret string
}

type SnsOauth2AuthorizeRequest

type SnsOauth2AuthorizeRequest struct {
	RedirectURL string
	AppID       string
	Scope       string `eg:"snsapi_base,snsapi_userinfo"`
	SourceURL   string
	State       string
	ForcePopup  bool
	// 快照模式 https://developers.weixin.qq.com/community/minihome/doc/000c2c34068880629ced91a2f56001?page=4#comment-list
	ForceSnapShot bool
}

type SnsUserInfoReply

type SnsUserInfoReply struct {
	// 微信公众平台用户信息相关接口调整公告官方: 公众号用户信息获取接口:不再返回用户性别及地区信息;
	// https://developers.weixin.qq.com/community/develop/doc/00028edbe3c58081e7cc834705b801
	Openid     string   `json:"openid"`
	Nickname   string   `json:"nickname"`
	Headimgurl string   `json:"headimgurl"`
	Privilege  []string `json:"privilege"`
	UnionID    string   `json:"unionid" note:"只有在用户将公众号绑定到微信开放平台帐号后,才会出现该字段。"`
}

type SnsUserInfoRequest

type SnsUserInfoRequest struct {
	AccessToken string
	OpenID      string
	Lang        string
}

type V3PayApiError

type V3PayApiError struct {
	StatusCode int         // 应答报文的 HTTP 状态码
	Header     http.Header // 应答报文的 Header 信息
	Body       string      // 应答报文的 Body 原文
	Code       string      `json:"code"`             // 应答报文的 Body 解析后的错误码信息,仅不符合预期/发生系统错误时存在
	Message    string      `json:"message"`          // 应答报文的 Body 解析后的文字说明信息,仅不符合预期/发生系统错误时存在
	Detail     interface{} `json:"detail,omitempty"` // 应答报文的 Body 解析后的详细信息,仅不符合预期/发生系统错误时存在
}

func (*V3PayApiError) Error

func (e *V3PayApiError) Error() string

type V3PayClient

type V3PayClient struct {
	Client  *core.Client
	Handler *notify.Handler
	// contains filtered or unexported fields
}

func NewV3PayClient

func NewV3PayClient(config V3PayConfig) (client *V3PayClient, err error)

func (V3PayClient) Notify

func (dep V3PayClient) Notify(ctx context.Context, request *http.Request) (tx payments.Transaction, err error)

func (V3PayClient) Refunds

func (dep V3PayClient) Refunds(ctx context.Context, req V3RefundsRequest) (refundResp refunddomestic.Refund, httpResult xhttp.HttpResult, apiError *V3PayApiError, err error)

func (V3PayClient) TransactionsJSAPI

func (dep V3PayClient) TransactionsJSAPI(ctx context.Context, req V3TransactionsJSAPIRequest) (reply V3TransactionsJSAPIReply, httpResult xhttp.HttpResult, apiError *V3PayApiError, err error)

TransactionsJSAPI https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml 商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后再按Native、JSAPI、APP等不同场景生成交易串调起支付。

Example
err := func(ctx context.Context) (err error) {
	var client *wx.V3PayClient
	if client, err = NewV3PayClient(); err != nil {
		return
	}
	var apiError *wx.V3PayApiError
	var httpResult xhttp.HttpResult
	var resp wx.V3TransactionsJSAPIReply
	if resp, httpResult, apiError, err = client.TransactionsJSAPI(ctx, wx.V3TransactionsJSAPIRequest{
		Appid:       "wxd678efh567hg6787",
		Mchid:       "1900009191",
		Description: "Image形象店-深圳腾大-QQ公仔",
		OutTradeNo:  "1217752501201407033233368018",
		Attach:      "自定义数据说明",
		NotifyUrl:   "https://www.weixin.qq.com/wxpay/pay.php",
		Amount: wx.V3TransactionsJSAPIRequestAmount{
			Total: 100,
		},
		Payer: wx.V3TransactionsJSAPIRequestPayer{
			Openid: "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o",
		},
	}); err != nil {
		return
	}
	if apiError != nil {
		log.Print("接口错误:\n", apiError.Error())
		log.Print("http:\n", httpResult.DumpRequestResponseString(true))
		return apiError
	}
	var id string = resp.PrepayId
	log.Print(id)
	return
}(context.Background())
log.Printf("%+v", err)
Output:

func (V3PayClient) TransferBatches

func (dep V3PayClient) TransferBatches(ctx context.Context, req V3TransferBatchesRequest) (
	reply V3TransferBatchesReply,
	httpResult xhttp.HttpResult,
	apiError *V3PayApiError,
	err error,
)

TransferBatches https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_1.shtml 商户可以通过该接口同时向多个用户微信零钱进行转账操作。

Example
err := func(ctx context.Context) (err error) {
	var client *wx.V3PayClient
	if client, err = NewV3PayClient(); err != nil {
		return
	}
	var apiError *wx.V3PayApiError
	var httpResult xhttp.HttpResult
	var resp wx.V3TransferBatchesReply
	if resp, httpResult, apiError, err = client.TransferBatches(ctx, wx.V3TransferBatchesRequest{
		Appid:       "wxf636efh567hg4356",
		OutBatchNo:  "plfk2020042013",
		BatchName:   "2019年1月深圳分部报销单",
		BatchRemark: "2019年1月深圳分部报销单",
		TotalAmount: 4000000,
		TotalNum:    200,
		TransferDetailList: []wx.V3TransferBatchesRequestDetail{{
			OutDetailNo:    "x23zy545Bd5436",
			TransferAmount: 200000,
			TransferRemark: "2020年4月报销",
			Openid:         "o-MYE42l80oelYMDE34nYD456Xoy",
			UserName:       "757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45",
		}},
		TransferSceneId: "1000",
	}); err != nil {
		return
	}
	if apiError != nil {
		log.Print("接口错误:\n", apiError.Error())
		log.Print("http:\n", httpResult.DumpRequestResponseString(true))
		return apiError
	}
	var id string = resp.BatchId
	log.Print(id)
	return
}(context.Background())
log.Printf("%+v", err)
Output:

func (V3PayClient) V3H5Pay

func (dep V3PayClient) V3H5Pay(ctx context.Context, req h5.PrepayRequest) (reply *h5.PrepayResponse, httpResult xhttp.HttpResult, apiError *V3PayApiError, err error)

V3H5Pay https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_1.shtml

type V3PayConfig

type V3PayConfig struct {
	APIClientKey            *rsa.PrivateKey `eg:"utils.LoadPrivateKeyWithPath(\"apiclient_key.pem\")"`
	MCHID                   string          `eg:"152000000"`
	CertificateSerialNumber string          `eg:"C731E2BFB6B3204E5B6B46F2044F5F7547BBEE47"`
	APIV3Key                string          `eg:"198bbc12f72649a99ac31bd5163a4c93"`
}

type V3RefundsRequest

type V3RefundsRequest struct {
	TransactionID   string
	OutTradeNo      string
	OutRefundNo     string
	Reason          string
	RefundAmountFen uint64
	GoodsName       string
	GoodsID         string
}

type V3TransactionsJSAPIReply

type V3TransactionsJSAPIReply struct {
	// 预支付交易会话标识
	PrepayId string `json:"prepay_id"`
	// 应用ID
	Appid string `json:"appId"`
	// 时间戳
	TimeStamp string `json:"timeStamp"`
	// 随机字符串
	NonceStr string `json:"nonceStr"`
	// 订单详情扩展字符串
	Package string `json:"package"`
	// 签名方式
	SignType string `json:"signType"`
	// 签名
	PaySign string `json:"paySign"`
}

type V3TransactionsJSAPIRequest

type V3TransactionsJSAPIRequest struct {
	Appid       string
	Mchid       string
	Description string
	OutTradeNo  string
	Attach      string
	NotifyUrl   string
	Amount      V3TransactionsJSAPIRequestAmount
	Payer       V3TransactionsJSAPIRequestPayer
}

type V3TransactionsJSAPIRequestAmount

type V3TransactionsJSAPIRequestAmount struct {
	Total    uint64
	Currency string
}

type V3TransactionsJSAPIRequestPayer

type V3TransactionsJSAPIRequestPayer struct {
	Openid string
}

type V3TransferBatchesReply

type V3TransferBatchesReply struct {
	// 商户系统内部的商家批次单号,在商户系统内部唯一
	OutBatchNo string
	// 微信批次单号,微信商家转账系统返回的唯一标识
	BatchId string
	// 批次受理成功时返回,按照使用rfc3339所定义的格式,格式为YYYY-MM-DDThh:mm:ss+TIMEZONE
	CreateTime time.Time
	// ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认 PROCESSING:转账中。已开始处理批次内的转账明细单 FINISHED:已完成。批次内的所有转账明细单都已处理完成 CLOSED:已关闭。可查询具体的批次关闭原因确认
	BatchStatus string
}

type V3TransferBatchesRequest

type V3TransferBatchesRequest struct {
	// 申请商户号的appid或商户号绑定的appid(企业号corpid即为此appid)
	Appid string
	// 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
	OutBatchNo string
	// 该笔批量转账的名称
	BatchName string
	// 转账说明,UTF8编码,最多允许32个字符
	BatchRemark string
	// 转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作
	TotalAmount int64
	// 一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作
	TotalNum int64
	// 发起批量转账的明细列表,最多一千笔
	TransferDetailList []V3TransferBatchesRequestDetail
	// 该批次转账使用的转账场景,如不填写则使用商家的默认场景,如无默认场景可为空,可前往“商家转账到零钱-前往功能”中申请。 如:1001-现金营销
	TransferSceneId string
}

func (V3TransferBatchesRequest) WechatSDK

type V3TransferBatchesRequestDetail

type V3TransferBatchesRequestDetail struct {
	// 商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成
	OutDetailNo string
	// 转账金额单位为“分”
	TransferAmount int64
	// 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符
	TransferRemark string
	// 商户appid下,某用户的openid
	Openid string
	// 收款方真实姓名。支持标准RSA算法和国密算法,公钥由微信侧提供 明细转账金额<0.3元时,不允许填写收款用户姓名 明细转账金额 >= 2,000元时,该笔明细必须填写收款用户姓名 同一批次转账明细中的姓名字段传入规则需保持一致,也即全部填写、或全部不填写 若商户传入收款用户姓名,微信支付会校验用户openID与姓名是否一致,并提供电子回单
	UserName string
}

TransferDetailInput

func (V3TransferBatchesRequestDetail) WechatSDK

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL