intelligence_finance_v1-202.../intelligence_finance_v1/generate.md

44 KiB
Raw Blame History

// File: intelligence_finance_v1/go.mod

module intelligence_finance_v1

go 1.21

// File: intelligence_finance_v1/crypto.go

package intelligence_finance_v1

import (
	"crypto/hmac"
	"crypto/rand"
	"crypto/sha256"
	"encoding/base64"
	"fmt"
	"math/big"
	"sort"
	"strings"
	"time"
)

// GenerateTimestamp 生成秒级时间戳字符串
func GenerateTimestamp() string {
	return fmt.Sprintf("%d", time.Now().Unix())
}

// GenerateNonce 生成指定长度的加密安全随机字符串
func GenerateNonce(length int) (string, error) {
	const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, length)
	for i := range b {
		num, err := rand.Int(rand.Reader, big.NewInt(int64(len(charset))))
		if err != nil {
			return "", err
		}
		b[i] = charset[num.Int64()]
	}
	return string(b), nil
}

// HmacSHA256Base64 使用HmacSHA256算法对数据进行签名返回Base64编码结果
func HmacSHA256Base64(secret, data string) string {
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write([]byte(data))
	return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

// BuildSignString 按字典序排序拼接参数(排除空值和签名字段)
func BuildSignString(params map[string]string) string {
	keys := make([]string, 0, len(params))
	for k, v := range params {
		if v != "" && k != "sign" && k != "signature" && k != "x-bfl-signature" {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)

	var parts []string
	for _, k := range keys {
		parts = append(parts, fmt.Sprintf("%s=%s", k, params[k]))
	}
	return strings.Join(parts, "&")
}

// BuildSignStringOrdered 按固定顺序拼接参数
func BuildSignStringOrdered(params map[string]string, orderedKeys []string) string {
	var parts []string
	for _, k := range orderedKeys {
		if v, ok := params[k]; ok && v != "" {
			parts = append(parts, fmt.Sprintf("%s=%s", k, v))
		}
	}
	return strings.Join(parts, "&")
}

// File: intelligence_finance_v1/types.go

package intelligence_finance_v1

// ============================================================
// 通用请求/响应结构
// ============================================================

// CommonResponse 通用API响应结构
type CommonResponse struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg,omitempty"`
	Data interface{} `json:"data,omitempty"`
}

// NotificationRequest 回调通知请求结构
type NotificationRequest struct {
	BizType string `json:"bizType"`
	BizID   string `json:"bizId"`
	Data    string `json:"data,omitempty"`
}

// ============================================================
// 接口1订单开票请求/响应
// ============================================================

// CreateInvoiceRequest 提交订单开票申请请求
type CreateInvoiceRequest struct {
	CompanyCode    string              `json:"companyCode,omitempty"`
	OrderID        string              `json:"orderId"`
	InvoiceType    int                 `json:"invoiceType"`
	Products       []InvoiceProduct    `json:"products"`
	Remark         string              `json:"remark,omitempty"`
	Purchaser      string              `json:"purchaser"`
	TaxNum         string              `json:"taxnum,omitempty"`
	PurchaserAddr  string              `json:"purchaserAddress,omitempty"`
	PurchaserTel   string              `json:"purchaserTel,omitempty"`
	BankName       string              `json:"bankName,omitempty"`
	BankAccount    string              `json:"bankAccount,omitempty"`
	Phone          string              `json:"phone,omitempty"`
	Email          string              `json:"email,omitempty"`
	ApplyPerson    string              `json:"applyPerson,omitempty"`
	Payee          string              `json:"payee,omitempty"`
	Reviewer       string              `json:"reviewer,omitempty"`
	InvoiceRemark  string              `json:"invoiceRemark,omitempty"`
	NaturalPerson  string              `json:"naturalPerson,omitempty"`
	AdditionInfo   string              `json:"additionInfo,omitempty"`
}

// InvoiceProduct 货物/服务明细
type InvoiceProduct struct {
	ProductName     string  `json:"productName"`
	RevenueCode     string  `json:"revenueCode"`
	AmountIncludeTax float64 `json:"amountIncludeTax"`
	Specs           string  `json:"specs,omitempty"`
	Unit            string  `json:"unit,omitempty"`
	Quantity        float64 `json:"quantity"`
	Discount        float64 `json:"discount,omitempty"`
	TaxSign         int     `json:"taxSign,omitempty"`
	TaxRate         float64 `json:"taxRate,omitempty"`
}

// CreateInvoiceResponse 提交订单开票申请响应
type CreateInvoiceResponse struct {
	Status    int              `json:"status"`
	ErrorMsg  string           `json:"errorMsg,omitempty"`
	DataList  []InvoiceData   `json:"dataList"`
}

// InvoiceData 发票数据
type InvoiceData struct {
	DeviceCode          string            `json:"deviceCode"`
	Drawer              string            `json:"drawer"`
	Email               string            `json:"email"`
	InvoiceType         string            `json:"invoiceType"`
	IssueType           string            `json:"issueType"`
	ListFlag            string            `json:"listFlag"`
	Mobile              string            `json:"mobile"`
	OriginalInvCode     string            `json:"originalInvCode,omitempty"`
	OriginalInvNo       string            `json:"originalInvNo,omitempty"`
	AdditionInfo        string            `json:"additionInfo,omitempty"`
	Payee               string            `json:"payee"`
	PurchaserAddress    string            `json:"purchaserAddress"`
	PurchaserBankAccount string           `json:"purchaserBankAccount"`
	PurchaserBankName   string            `json:"purchaserBankName"`
	PurchaserName       string            `json:"purchaserName"`
	PurchaserTaxNo      string            `json:"purchaserTaxNo"`
	PurchaserTel        string            `json:"purchaserTel"`
	NaturalPerson       string            `json:"naturalPerson,omitempty"`
	Remark              string            `json:"remark"`
	Reviewer            string            `json:"reviewer"`
	SellerAddress       string            `json:"sellerAddress,omitempty"`
	SellerBankAccount   string            `json:"sellerBankAccount"`
	SellerBankName      string            `json:"sellerBankName"`
	SellerName          string            `json:"sellerName"`
	CheckCode           string            `json:"checkCode"`
	CipherText          string            `json:"cipherText"`
	DrewDate            string            `json:"drewDate,omitempty"`
	InvoiceCode         string            `json:"invoiceCode"`
	InvoiceNo           string            `json:"invoiceNo"`
	InvoiceStatus       string            `json:"invoiceStatus"`
	LayoutFileURL       string            `json:"layoutFileUrl,omitempty"`
	PdfURL              string            `json:"pdfUrl,omitempty"`
	OfdURL              string            `json:"ofdUrl,omitempty"`
	XmlURL              string            `json:"xmlUrl,omitempty"`
	TotalExcludeTax     string            `json:"totalExcludeTax"`
	TotalIncludeTax     string            `json:"totalIncludeTax"`
	TotalTaxAmount      string            `json:"totalTaxAmount"`
	LevyingType         string            `json:"levyingType"`
	Details             []InvoiceDetail   `json:"details"`
}

// InvoiceDetail 商品明细
type InvoiceDetail struct {
	Amount             string `json:"amount,omitempty"`
	Quantity           string `json:"quantity,omitempty"`
	DeductionAmount    string `json:"deductionAmount,omitempty"`
	TaxAmount          string `json:"taxAmount,omitempty"`
	ItemTitle          string `json:"itemTitle"`
	TaxCode            string `json:"taxCode"`
	ItemType           string `json:"itemType"`
	ItemName           string `json:"itemName"`
	Specs              string `json:"specs,omitempty"`
	TaxFreePolicy      string `json:"taxFreePolicy"`
	PreferentialPolicy string `json:"preferentialPolicy"`
	TaxRate            string `json:"taxRate"`
	TaxSign            string `json:"taxSign"`
	Unit               string `json:"unit,omitempty"`
	UnitPrice          string `json:"unitPrice,omitempty"`
}

// ============================================================
// 接口2开票状态查询请求/响应
// ============================================================

// QueryInvoiceStatusRequest 查询订单开票状态请求
type QueryInvoiceStatusRequest struct {
	OrderID string `json:"orderId"`
}

// QueryInvoiceStatusResponse 查询订单开票状态响应
type QueryInvoiceStatusResponse struct {
	Status  int            `json:"status"`
	Message string         `json:"message"`
	Data    []InvoiceData  `json:"data"`
}

// ============================================================
// 接口3创建付款单据请求/响应
// ============================================================

// CreatePaymentRequest 创建付款单据请求
type CreatePaymentRequest struct {
	Code                     string              `json:"code"`
	YidaAppType              string              `json:"yidaAppType,omitempty"`
	EmpAccountUserID         string              `json:"empAccountUserId,omitempty"`
	Department               *Department         `json:"department,omitempty"`
	Usage                    string              `json:"usage,omitempty"`
	PaymentUserID            string              `json:"paymentUserId,omitempty"`
	Customer                 *Customer           `json:"customer,omitempty"`
	PrincipalID              string              `json:"principalId,omitempty"`
	Remark                   string              `json:"remark,omitempty"`
	Supplier                 *Supplier           `json:"supplier,omitempty"`
	Title                    string              `json:"title,omitempty"`
	Project                  *Project            `json:"project,omitempty"`
	PaymentUserIDListStr     string              `json:"paymentUserIdListStr,omitempty"`
	NeedPayment              bool                `json:"needPayment,omitempty"`
	PaymentDetailListJsonStr string              `json:"paymentDetailListJsonStr,omitempty"`
	PaymentDetailList        []PaymentDetail     `json:"paymentDetailList,omitempty"`
	Company                  *Company            `json:"company,omitempty"`
	Amount                   string              `json:"amount,omitempty"`
	RecipientAccountInfo     *RecipientAccount   `json:"recipientAccountInfo,omitempty"`
	EnterpriseAccount        *EnterpriseAccount  `json:"enterpriseAccount,omitempty"`
	Category                 []Category          `json:"category,omitempty"`
	UserID                   string              `json:"userId"`
	OccurDate                int64               `json:"occurDate,omitempty"`
	Product                  *Product            `json:"product,omitempty"`
	YidaFormUUID             string              `json:"yidaFormUuid,omitempty"`
	CanEditPaymentInfo       bool                `json:"canEditPaymentInfo,omitempty"`
	PaymentUserIDList        []string            `json:"paymentUserIdList,omitempty"`
	YidaProcInsID            string              `json:"yidaProcInsId,omitempty"`
	SyncPaymentOrder         bool                `json:"syncPaymentOrder,omitempty"`
}

// Department 部门信息
type Department struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Customer 客户信息
type Customer struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Supplier 供应商信息
type Supplier struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Project 项目信息
type Project struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Category 收支类别信息
type Category struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Product 商品信息
type Product struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// Company 企业主体信息
type Company struct {
	Code string `json:"code,omitempty"`
	Name string `json:"name"`
}

// EnterpriseAccount 企业账号信息
type EnterpriseAccount struct {
	EnterpriseAccountCode string `json:"enterpriseAccountCode,omitempty"`
	AccountCategory       string `json:"accountCategory"`
	AccountType           string `json:"accountType,omitempty"`
	CardNo                string `json:"cardNo,omitempty"`
	AccountName           string `json:"accountName,omitempty"`
	OfficialNumber        string `json:"officialNumber,omitempty"`
	OfficialName          string `json:"officialName,omitempty"`
	Name                  string `json:"name,omitempty"`
	Code                  string `json:"code,omitempty"`
	City                  string `json:"city,omitempty"`
	Province              string `json:"province,omitempty"`
}

// RecipientAccount 收款账户信息
type RecipientAccount struct {
	AccountCategory string `json:"accountCategory"`
	AccountType     string `json:"accountType,omitempty"`
	CardNo          string `json:"cardNo,omitempty"`
	AccountName     string `json:"accountName,omitempty"`
}

// PaymentDetail 付款明细
type PaymentDetail struct {
	Amount       string       `json:"amount,omitempty"`
	InvoiceInfo  *InvoiceInfo `json:"invoiceInfo,omitempty"`
	ProductCode  string       `json:"productCode,omitempty"`
	ProjectCode  string       `json:"projectCode,omitempty"`
	Remark       string       `json:"remark,omitempty"`
	PrincipalID  string       `json:"principalId,omitempty"`
	Tax          string       `json:"tax,omitempty"`
}

// InvoiceInfo 付款明细发票信息
type InvoiceInfo struct {
	InvoiceNo   string `json:"invoiceNo,omitempty"`
	InvoiceCode string `json:"invoiceCode,omitempty"`
}

// CreatePaymentResponse 创建付款单据响应
type CreatePaymentResponse struct {
	Code string `json:"code"`
}

// ============================================================
// 接口4支付完成通知平台回调
// ============================================================

// PaymentNotification 支付完成通知数据结构
type PaymentNotification struct {
	Code                string                `json:"code"`
	InstanceID          string                `json:"instanceId"`
	CorpID              string                `json:"corpId"`
	PaymentStatus       string                `json:"paymentStatus"`
	PaymentTime         string                `json:"paymentTime"`
	UserID              string                `json:"userId"`
	FailReason          string                `json:"failReason,omitempty"`
	PayerAccountInfo    *PayerAccountInfo     `json:"payerAccountInfo,omitempty"`
	PayeeAccountInfo    *PayeeAccountInfo     `json:"payeeAccountInfo,omitempty"`
	RelatedRowNumberList []string             `json:"relatedRowNumberList,omitempty"`
	Source              string                `json:"source,omitempty"`
	Template            string                `json:"template,omitempty"`
	Amount              string                `json:"amount,omitempty"`
}

// PayerAccountInfo 付款账户信息
type PayerAccountInfo struct {
	BankOpenDTO          *BankOpenDTO `json:"bankOpenDTO,omitempty"`
	EnterpriseAccountCode string      `json:"enterpriseAccountCode,omitempty"`
	AccountType          string       `json:"accountType,omitempty"`
}

// PayeeAccountInfo 收款账户信息
type PayeeAccountInfo struct {
	BankOpenDTO *BankOpenDTO `json:"bankOpenDTO,omitempty"`
}

// BankOpenDTO 银行信息
type BankOpenDTO struct {
	BankCode       string `json:"bankCode,omitempty"`
	BankName       string `json:"bankName,omitempty"`
	BankBranchCode string `json:"bankBranchCode,omitempty"`
	BankBranchName string `json:"bankBranchName,omitempty"`
	AccountName    string `json:"accountName,omitempty"`
	BankCardNo     string `json:"bankCardNo,omitempty"`
	Type           string `json:"type,omitempty"`
}

// ============================================================
// 接口5支付状态查询请求/响应
// ============================================================

// QueryPaymentStatusRequest 查询支付状态请求
type QueryPaymentStatusRequest struct {
	Code   string `json:"code"`
	UserID string `json:"userId"`
}

// QueryPaymentStatusResponse 查询支付状态响应与PaymentNotification结构一致
type QueryPaymentStatusResponse struct {
	PaymentNotification
}

// ============================================================
// 接口6创建供应商请求/响应
// ============================================================

// CreateSupplierRequest 创建供应商请求
type CreateSupplierRequest struct {
	InvokeID string              `json:"invokeId,omitempty"`
	UserID   string              `json:"userId"`
	Data     string              `json:"data,omitempty"`
	BizType  string              `json:"bizType"`
}

// CreateSupplierBizData 创建供应商业务数据
type CreateSupplierBizData struct {
	CorpID       string         `json:"corpId"`
	Creator      string         `json:"creator"`
	SupplierInfo *SupplierInfo  `json:"supplierInfo,omitempty"`
}

// SupplierInfo 供应商数据
type SupplierInfo struct {
	Name                     string `json:"name"`
	CorpID                   string `json:"corpId"`
	UserDefineCode           string `json:"userDefineCode,omitempty"`
	Description              string `json:"description,omitempty"`
	ContactAddress           string `json:"contactAddress,omitempty"`
	ContactCompanyTelephone  string `json:"contactCompanyTelephone,omitempty"`
	ContactEmail             string `json:"contactEmail,omitempty"`
	ContactName              string `json:"contactName,omitempty"`
	ContactTelephone         string `json:"contactTelephone,omitempty"`
	Creator                  string `json:"creator"`
	InvoiceAccount           string `json:"invoiceAccount,omitempty"`
	InvoiceAddress           string `json:"invoiceAddress,omitempty"`
	InvoiceBankName          string `json:"invoiceBankName,omitempty"`
	InvoiceName              string `json:"invoiceName,omitempty"`
	InvoiceTaxNo             string `json:"invoiceTaxNo,omitempty"`
	PurchaserTel             string `json:"purchaserTel,omitempty"`
	BankName                 string `json:"bankName,omitempty"`
	InvoiceTelephone         string `json:"invoiceTelephone,omitempty"`
	AccountName              string `json:"accountName,omitempty"`
	AccountType              string `json:"accountType,omitempty"`
}

// CreateSupplierResponse 创建供应商响应
type CreateSupplierResponse struct {
	InvokeID string                    `json:"invokeId,omitempty"`
	BizType  string                    `json:"bizType"`
	Data     string                    `json:"data,omitempty"`
}

// CreateSupplierResponseData 创建供应商响应数据
type CreateSupplierResponseData struct {
	Result  string `json:"result,omitempty"`
	Success bool   `json:"success"`
}

// SupplierInfoResponse 供应商信息(响应)
type SupplierInfoResponse struct {
	SupplierID              string `json:"supplierId"`
	SupplierName            string `json:"supplierName"`
	Name                    string `json:"name"`
	CorpID                  string `json:"corpId"`
	UserDefineCode          string `json:"userDefineCode,omitempty"`
	Description             string `json:"description,omitempty"`
	ContactAddress          string `json:"contactAddress,omitempty"`
	ContactCompanyTelephone string `json:"contactCompanyTelephone,omitempty"`
	ContactEmail            string `json:"contactEmail,omitempty"`
	ContactName             string `json:"contactName,omitempty"`
	ContactTelephone        string `json:"contactTelephone,omitempty"`
	Creator                 string `json:"creator"`
	InvoiceAccount          string `json:"invoiceAccount,omitempty"`
	InvoiceAddress          string `json:"invoiceAddress,omitempty"`
	InvoiceBankName         string `json:"invoiceBankName,omitempty"`
}

// ============================================================
// 接口7根据名称查询供应商请求/响应
// ============================================================

// QuerySupplierByNameRequest 根据名称查询供应商请求
type QuerySupplierByNameRequest struct {
	InvokeID string                    `json:"invokeId,omitempty"`
	UserID   string                    `json:"userId"`
	Data     string                    `json:"data,omitempty"`
	BizType  string                    `json:"bizType"`
}

// QuerySupplierByNameBizData 根据名称查询供应商业务数据
type QuerySupplierByNameBizData struct {
	CorpID string `json:"corpId"`
	Name   string `json:"name"`
}

// QuerySupplierByNameResponse 根据名称查询供应商响应
type QuerySupplierByNameResponse struct {
	InvokeID string                    `json:"invokeId,omitempty"`
	BizType  string                    `json:"bizType"`
	Data     string                    `json:"data,omitempty"`
	Result   string                    `json:"result,omitempty"`
	Success  bool                      `json:"success"`
}

// QuerySupplierByNameResult 供应商查询结果重要字段
type QuerySupplierByNameResult struct {
	SupplierName            string `json:"supplierName"`
	UserDefineCode          string `json:"userDefineCode,omitempty"`
	InvoiceName             string `json:"invoiceName,omitempty"`
	SupplierID              string `json:"supplierId"`
	CorpID                  string `json:"corpId"`
	ContactTelephone        string `json:"contactTelephone,omitempty"`
	ContactEmail            string `json:"contactEmail,omitempty"`
	ContactName             string `json:"contactName,omitempty"`
	InvoiceBankName         string `json:"invoiceBankName,omitempty"`
	InvoiceAccount          string `json:"invoiceAccount,omitempty"`
	Description             string `json:"description,omitempty"`
	InvoiceAddress          string `json:"invoiceAddress,omitempty"`
	InvoiceTaxNo            string `json:"invoiceTaxNo,omitempty"`
	ContactCompanyTelephone string `json:"contactCompanyTelephone,omitempty"`
	CreateTime              int64  `json:"createTime,omitempty"`
	InvoiceTelephone        string `json:"invoiceTelephone,omitempty"`
	ContactAddress          string `json:"contactAddress,omitempty"`
}

// ============================================================
// 接口8更新供应商请求/响应
// ============================================================

// UpdateSupplierRequest 更新供应商请求
type UpdateSupplierRequest struct {
	InvokeID string                  `json:"invokeId,omitempty"`
	UserID   string                  `json:"userId"`
	Data     string                  `json:"data,omitempty"`
	BizType  string                  `json:"bizType"`
}

// UpdateSupplierBizData 更新供应商业务数据
type UpdateSupplierBizData struct {
	SupplierID              string `json:"supplierId"`
	Name                    string `json:"name"`
	CorpID                  string `json:"corpId"`
	UserDefineCode          string `json:"userDefineCode,omitempty"`
	Description             string `json:"description,omitempty"`
	ContactAddress          string `json:"contactAddress,omitempty"`
	ContactCompanyTelephone string `json:"contactCompanyTelephone,omitempty"`
	ContactEmail            string `json:"contactEmail,omitempty"`
	ContactName             string `json:"contactName,omitempty"`
	ContactTelephone        string `json:"contactTelephone,omitempty"`
	UserID                  string `json:"userId"`
	InvoiceAccount          string `json:"invoiceAccount,omitempty"`
	InvoiceAddress          string `json:"invoiceAddress,omitempty"`
	InvoiceBankName         string `json:"invoiceBankName,omitempty"`
	InvoiceName             string `json:"invoiceName,omitempty"`
	InvoiceTaxNo            string `json:"invoiceTaxNo,omitempty"`
	PurchaserTel            string `json:"purchaserTel,omitempty"`
	BankName                string `json:"bankName,omitempty"`
	InvoiceTelephone        string `json:"invoiceTelephone,omitempty"`
	AccountName             string `json:"accountName,omitempty"`
	AccountType             string `json:"accountType,omitempty"`
	BankBranchCode          string `json:"bankBranchCode,omitempty"`
	BankCode                string `json:"bankCode,omitempty"`
	BankCity                string `json:"bankCity,omitempty"`
	BankProvince            string `json:"bankProvince,omitempty"`
}

// UpdateSupplierResponse 更新供应商响应
type UpdateSupplierResponse struct {
	InvokeID string                    `json:"invokeId,omitempty"`
	BizType  string                    `json:"bizType"`
	Data     string                    `json:"data,omitempty"`
}

// UpdateSupplierResponseData 更新供应商响应数据
type UpdateSupplierResponseData struct {
	Result  string `json:"result,omitempty"`
	Success bool   `json:"success"`
}

// ============================================================
// 接口9根据用户自定义编码查询供应商请求/响应
// ============================================================

// QuerySupplierByUserDefineCodeRequest 根据用户自定义编码查询供应商请求
type QuerySupplierByUserDefineCodeRequest struct {
	InvokeID string   `json:"invokeId,omitempty"`
	UserID   string   `json:"userId"`
	Data     string   `json:"data,omitempty"`
	BizType  string   `json:"bizType"`
}

// QuerySupplierByUserDefineCodeBizData 根据自定义编码查询供应商业务数据
type QuerySupplierByUserDefineCodeBizData struct {
	CorpID         string `json:"corpId"`
	UserDefineCode string `json:"userDefineCode"`
}

// QuerySupplierByUserDefineCodeResponse 根据自定义编码查询供应商响应
type QuerySupplierByUserDefineCodeResponse struct {
	InvokeID string                               `json:"invokeId,omitempty"`
	BizType  string                               `json:"bizType"`
	Data     string                               `json:"data,omitempty"`
}

// QuerySupplierByUserDefineCodeResponseData 响应数据
type QuerySupplierByUserDefineCodeResponseData struct {
	Success bool `json:"success"`
}

// QuerySupplierByUserDefineCodeResult 供应商查询结果重要字段
type QuerySupplierByUserDefineCodeResult struct {
	UserDefineCode string `json:"userDefineCode"`
	SupplierName   string `json:"supplierName"`
	ModifiedTime   int64  `json:"modifiedTime,omitempty"`
	Creator        string `json:"creator,omitempty"`
	SupplierID     string `json:"supplierId"`
	Code           string `json:"code,omitempty"`
	CorpID         string `json:"corpId"`
	CreateTime     int64  `json:"createTime,omitempty"`
	Name           string `json:"name"`
	ID             int64  `json:"id,omitempty"`
	Status         string `json:"status,omitempty"`
}

// File: intelligence_finance_v1/errors.go

package intelligence_finance_v1

import "fmt"

// SDKError SDK通用错误类型
type SDKError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
	Err     error  `json:"-"`
}

// Error 实现error接口
func (e *SDKError) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("code=%d, message=%s, err=%v", e.Code, e.Message, e.Err)
	}
	return fmt.Sprintf("code=%d, message=%s", e.Code, e.Message)
}

// Unwrap 返回包装的错误
func (e *SDKError) Unwrap() error {
	return e.Err
}

// NewSDKError 创建SDK错误
func NewSDKError(code int, message string, err error) *SDKError {
	return &SDKError{
		Code:    code,
		Message: message,
		Err:     err,
	}
}

// 预定义错误码
const (
	ErrCodeSuccess          = 0
	ErrCodeUnknown          = -1
	ErrCodeInvalidParam     = 1001
	ErrCodeSignatureFailed  = 1002
	ErrCodeNetworkError     = 1003
	ErrCodeRequestTimeout   = 1004
	ErrCodeServerError      = 2001
	ErrCodeUnauthorized     = 2002
	ErrCodeNotFound         = 2003
	ErrCodeRateLimit        = 2004
)

// 预定义错误
var (
	ErrUnknown        = NewSDKError(ErrCodeUnknown, "未知错误", nil)
	ErrInvalidParam   = NewSDKError(ErrCodeInvalidParam, "参数无效", nil)
	ErrSignatureFailed = NewSDKError(ErrCodeSignatureFailed, "签名失败", nil)
	ErrNetworkError   = NewSDKError(ErrCodeNetworkError, "网络错误", nil)
	ErrRequestTimeout = NewSDKError(ErrCodeRequestTimeout, "请求超时", nil)
	ErrServerError    = NewSDKError(ErrCodeServerError, "服务端错误", nil)
	ErrUnauthorized   = NewSDKError(ErrCodeUnauthorized, "未授权", nil)
	ErrNotFound       = NewSDKError(ErrCodeNotFound, "未找到", nil)
	ErrRateLimit      = NewSDKError(ErrCodeRateLimit, "请求频率限制", nil)
)

// File: intelligence_finance_v1/client.go

package intelligence_finance_v1

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"time"
)

// Client 业财连接SDK客户端
type Client struct {
	baseURL      string
	tenantID     string
	clientID     string
	clientSecret string
	httpClient   *http.Client
	debug        bool
}

// ClientOption 客户端配置选项
type ClientOption func(*Client)

// WithHTTPClient 设置自定义HTTP客户端
func WithHTTPClient(httpClient *http.Client) ClientOption {
	return func(c *Client) {
		c.httpClient = httpClient
	}
}

// WithDebug 开启调试模式
func WithDebug(debug bool) ClientOption {
	return func(c *Client) {
		c.debug = debug
	}
}

// WithTimeout 设置请求超时时间
func WithTimeout(timeout time.Duration) ClientOption {
	return func(c *Client) {
		c.httpClient.Timeout = timeout
	}
}

// NewClient 创建新的SDK客户端
//   - baseURL: API基础地址
//   - tenantID: 平台分配的租户唯一标识
//   - clientID: 平台分配的应用标识
//   - clientSecret: 平台分配的客户端密钥
//   - opts: 可选配置项
func NewClient(baseURL, tenantID, clientID, clientSecret string, opts ...ClientOption) *Client {
	c := &Client{
		baseURL:      baseURL,
		tenantID:     tenantID,
		clientID:     clientID,
		clientSecret: clientSecret,
		httpClient: &http.Client{
			Timeout: 30 * time.Second,
		},
	}
	for _, opt := range opts {
		opt(c)
	}
	return c
}

// doRequest 发送HTTP请求自动添加签名和认证头
func (c *Client) doRequest(ctx context.Context, path string, request interface{}, response interface{}) error {
	bodyBytes, err := json.Marshal(request)
	if err != nil {
		return NewSDKError(ErrCodeInvalidParam, "请求序列化失败", err)
	}

	if c.debug {
		fmt.Printf("[DEBUG] Request URL: %s%s\n", c.baseURL, path)
		fmt.Printf("[DEBUG] Request Body: %s\n", string(bodyBytes))
	}

	// 生成时间戳和随机数
	timestamp := GenerateTimestamp()
	nonce, err := GenerateNonce(16)
	if err != nil {
		return NewSDKError(ErrCodeSignatureFailed, "生成随机数失败", err)
	}

	// 签名数据timestamp + nonce
	signData := timestamp + nonce
	signature := HmacSHA256Base64(c.clientSecret, signData)

	req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.baseURL+path, bytes.NewReader(bodyBytes))
	if err != nil {
		return NewSDKError(ErrCodeNetworkError, "创建请求失败", err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("tenant-id", c.tenantID)
	req.Header.Set("client-id", c.clientID)
	req.Header.Set("x-bfl-signature-timestamp", timestamp)
	req.Header.Set("x-bfl-signature-nonce", nonce)
	req.Header.Set("x-bfl-signature", signature)

	if c.debug {
		fmt.Printf("[DEBUG] Headers: tenant-id=%s, client-id=%s, x-bfl-signature=%s\n", c.tenantID, c.clientID, signature)
	}

	resp, err := c.httpClient.Do(req)
	if err != nil {
		return NewSDKError(ErrCodeNetworkError, "请求发送失败", err)
	}
	defer resp.Body.Close()

	respBody, err := io.ReadAll(resp.Body)
	if err != nil {
		return NewSDKError(ErrCodeNetworkError, "读取响应失败", err)
	}

	if c.debug {
		fmt.Printf("[DEBUG] Response Status: %s\n", resp.Status)
		fmt.Printf("[DEBUG] Response Body: %s\n", string(respBody))
	}

	// 解析通用响应
	var commonResp CommonResponse
	if err := json.Unmarshal(respBody, &commonResp); err != nil {
		return NewSDKError(ErrCodeUnknown, "响应解析失败", err)
	}

	if commonResp.Code != 0 {
		return NewSDKError(commonResp.Code, commonResp.Msg, nil)
	}

	// 如果有data字段且response不为nil反序列化data到response
	if commonResp.Data != nil && response != nil {
		dataBytes, err := json.Marshal(commonResp.Data)
		if err != nil {
			return NewSDKError(ErrCodeUnknown, "响应数据序列化失败", err)
		}
		if err := json.Unmarshal(dataBytes, response); err != nil {
			return NewSDKError(ErrCodeUnknown, "响应数据解析失败", err)
		}
	}

	return nil
}

// ============================================================
// 接口1订单开票
// ============================================================

// CreateInvoice 提交订单开票申请
// 文档接口1 - 提交订单开票申请
func (c *Client) CreateInvoice(ctx context.Context, req *CreateInvoiceRequest) (*CreateInvoiceResponse, error) {
	path := "/api/v1/invoice/create"
	var resp CreateInvoiceResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口2开票状态查询
// ============================================================

// QueryInvoiceStatus 查询订单开票状态
// 文档接口2 - 查询订单开票状态
func (c *Client) QueryInvoiceStatus(ctx context.Context, req *QueryInvoiceStatusRequest) (*QueryInvoiceStatusResponse, error) {
	path := "/api/v1/invoice/query"
	var resp QueryInvoiceStatusResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口3创建付款单据
// ============================================================

// CreatePayment 创建付款单据
// 文档接口3 - 创建付款单据
func (c *Client) CreatePayment(ctx context.Context, req *CreatePaymentRequest) (*CreatePaymentResponse, error) {
	path := "/api/v1/payment/create"
	var resp CreatePaymentResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口4支付完成通知平台回调客户
// 此接口由客户提供平台调用。客户需实现HTTP Handler处理回调。
// ============================================================

// HandlePaymentNotification 处理支付完成通知
// 文档接口4 - 支付完成通知回调处理
// 该函数用于解析平台发起的支付完成通知请求返回SUCCESS或FAILED
func HandlePaymentNotification(body []byte) (string, error) {
	var notification PaymentNotification
	if err := json.Unmarshal(body, &notification); err != nil {
		return "FAILED", NewSDKError(ErrCodeInvalidParam, "解析通知数据失败", err)
	}
	// 业务处理由调用方自行实现,此处仅返回成功
	// 调用方应在此函数基础上扩展业务逻辑
	return "SUCCESS", nil
}

// ============================================================
// 接口5支付状态查询
// ============================================================

// QueryPaymentStatus 查询支付状态
// 文档接口5 - 查询支付状态
func (c *Client) QueryPaymentStatus(ctx context.Context, req *QueryPaymentStatusRequest) (*QueryPaymentStatusResponse, error) {
	path := "/api/v1/payment/query"
	var resp QueryPaymentStatusResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口6创建供应商
// ============================================================

// CreateSupplier 创建供应商
// 文档接口6 - 创建供应商
func (c *Client) CreateSupplier(ctx context.Context, req *CreateSupplierRequest) (*CreateSupplierResponse, error) {
	path := "/api/v1/supplier/create"
	var resp CreateSupplierResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口7根据名称查询供应商
// ============================================================

// QuerySupplierByName 根据供应商名称查询供应商
// 文档接口7 - 根据名称查询供应商
func (c *Client) QuerySupplierByName(ctx context.Context, req *QuerySupplierByNameRequest) (*QuerySupplierByNameResponse, error) {
	path := "/api/v1/supplier/queryByName"
	var resp QuerySupplierByNameResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口8更新供应商
// ============================================================

// UpdateSupplier 更新供应商信息
// 文档接口8 - 更新供应商
func (c *Client) UpdateSupplier(ctx context.Context, req *UpdateSupplierRequest) (*UpdateSupplierResponse, error) {
	path := "/api/v1/supplier/update"
	var resp UpdateSupplierResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// ============================================================
// 接口9根据用户自定义编码查询供应商
// ============================================================

// QuerySupplierByUserDefineCode 根据用户自定义编码查询供应商
// 文档接口9 - 根据用户自定义编码查询供应商
func (c *Client) QuerySupplierByUserDefineCode(ctx context.Context, req *QuerySupplierByUserDefineCodeRequest) (*QuerySupplierByUserDefineCodeResponse, error) {
	path := "/api/v1/supplier/queryByCode"
	var resp QuerySupplierByUserDefineCodeResponse
	if err := c.doRequest(ctx, path, req, &resp); err != nil {
		return nil, err
	}
	return &resp, nil
}

// File: intelligence_finance_v1/example_test.go

package intelligence_finance_v1

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"
)

// ExampleNewClient 展示了如何创建SDK客户端
func ExampleNewClient() {
	// 创建客户端
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
		WithTimeout(30*time.Second),
		WithDebug(true),
	)
	_ = client
	fmt.Println("Client created successfully")
}

// ExampleClient_CreateInvoice 展示了如何提交订单开票申请
func ExampleClient_CreateInvoice() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	req := &CreateInvoiceRequest{
		OrderID:     "ORDER20240101001",
		InvoiceType: 9, // 数电普票
		Purchaser:   "测试购买方有限公司",
		TaxNum:      "91110108MA12345678",
		Phone:       "13800138000",
		Email:       "test@example.com",
		Products: []InvoiceProduct{
			{
				ProductName:      "办公用品",
				RevenueCode:      "1090515010000000000",
				AmountIncludeTax: 1130.00,
				Quantity:         10,
				Unit:             "个",
				TaxRate:          0.13,
				TaxSign:          1,
				Discount:         0,
			},
		},
		ApplyPerson: "张三",
		Payee:       "李四",
		Reviewer:    "王五",
	}

	resp, err := client.CreateInvoice(context.Background(), req)
	if err != nil {
		log.Fatalf("创建开票申请失败: %v", err)
	}

	fmt.Printf("开票状态: %d, 错误信息: %s\n", resp.Status, resp.ErrorMsg)
	for i, inv := range resp.DataList {
		fmt.Printf("发票%d: 代码=%s, 号码=%s, 金额(含税)=%s\n", i+1, inv.InvoiceCode, inv.InvoiceNo, inv.TotalIncludeTax)
	}
}

// ExampleClient_QueryInvoiceStatus 展示了如何查询开票状态
func ExampleClient_QueryInvoiceStatus() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	req := &QueryInvoiceStatusRequest{
		OrderID: "ORDER20240101001",
	}

	resp, err := client.QueryInvoiceStatus(context.Background(), req)
	if err != nil {
		log.Fatalf("查询开票状态失败: %v", err)
	}

	fmt.Printf("开票状态: %d, 描述: %s\n", resp.Status, resp.Message)
}

// ExampleClient_CreatePayment 展示了如何创建付款单据
func ExampleClient_CreatePayment() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	req := &CreatePaymentRequest{
		Code:   "PAY20240101001",
		UserID: "user123",
		Title:  "采购付款-2024年1月",
		Amount: "50000.00",
		Supplier: &Supplier{
			Name: "供应商A",
		},
		Department: &Department{
			Name: "财务部",
		},
		Company: &Company{
			Name: "XX科技有限公司",
		},
		PaymentDetailList: []PaymentDetail{
			{
				Amount: "50000.00",
				Remark: "1月采购货款",
			},
		},
	}

	resp, err := client.CreatePayment(context.Background(), req)
	if err != nil {
		log.Fatalf("创建付款单据失败: %v", err)
	}

	fmt.Printf("付款单据编码: %s\n", resp.Code)
}

// ExampleHandlePaymentNotification 展示了如何处理支付完成通知
func ExampleHandlePaymentNotification() {
	// 模拟平台回调的请求体
	notificationBody := `{
		"code": "PAY20240101001",
		"instanceId": "instance_001",
		"corpId": "dingXXXXXX",
		"paymentStatus": "SUCCESS",
		"paymentTime": "2024-01-15 10:30:00",
		"userId": "user123",
		"amount": "50000.00",
		"source": "openapi"
	}`

	result, err := HandlePaymentNotification([]byte(notificationBody))
	if err != nil {
		log.Printf("处理通知失败: %v", err)
	}

	fmt.Printf("通知处理结果: %s\n", result)

	// 实际业务中,可以在此处解析通知数据并执行后续操作
	var notification PaymentNotification
	if err := json.Unmarshal([]byte(notificationBody), &notification); err == nil {
		fmt.Printf("收到支付通知: 单据编码=%s, 支付状态=%s\n", notification.Code, notification.PaymentStatus)
	}
}

// ExampleClient_QueryPaymentStatus 展示了如何查询支付状态
func ExampleClient_QueryPaymentStatus() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	req := &QueryPaymentStatusRequest{
		Code:   "PAY20240101001",
		UserID: "user123",
	}

	resp, err := client.QueryPaymentStatus(context.Background(), req)
	if err != nil {
		log.Fatalf("查询支付状态失败: %v", err)
	}

	fmt.Printf("支付状态: %s, 支付时间: %s\n", resp.PaymentStatus, resp.PaymentTime)
}

// ExampleClient_CreateSupplier 展示了如何创建供应商
func ExampleClient_CreateSupplier() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	bizData := CreateSupplierBizData{
		CorpID:  "dingXXXXXX",
		Creator: "user123",
		SupplierInfo: &SupplierInfo{
			Name:            "测试供应商有限公司",
			CorpID:          "dingXXXXXX",
			Creator:         "user123",
			UserDefineCode:  "SUP-001",
			ContactName:     "张三",
			ContactTelephone: "13800138000",
			ContactEmail:    "contact@supplier.com",
			ContactAddress:  "北京市朝阳区XX路XX号",
		},
	}

	bizDataBytes, _ := json.Marshal(bizData)

	req := &CreateSupplierRequest{
		InvokeID: "invoke_001",
		UserID:   "user123",
		Data:     string(bizDataBytes),
		BizType:  "create_supplier",
	}

	resp, err := client.CreateSupplier(context.Background(), req)
	if err != nil {
		log.Fatalf("创建供应商失败: %v", err)
	}

	fmt.Printf("创建供应商响应: invokeId=%s, bizType=%s\n", resp.InvokeID, resp.BizType)
}

// ExampleClient_QuerySupplierByName 展示了如何根据名称查询供应商
func ExampleClient_QuerySupplierByName() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	bizData := []QuerySupplierByNameBizData{
		{
			CorpID: "dingXXXXXX",
			Name:   "测试供应商有限公司",
		},
	}

	bizDataBytes, _ := json.Marshal(bizData)

	req := &QuerySupplierByNameRequest{
		InvokeID: "invoke_002",
		UserID:   "user123",
		Data:     string(bizDataBytes),
		BizType:  "query_supplier_by_name",
	}

	resp, err := client.QuerySupplierByName(context.Background(), req)
	if err != nil {
		log.Fatalf("查询供应商失败: %v", err)
	}

	fmt.Printf("查询结果: success=%v, result=%s\n", resp.Success, resp.Result)
}

// ExampleClient_UpdateSupplier 展示了如何更新供应商
func ExampleClient_UpdateSupplier() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	bizData := UpdateSupplierBizData{
		SupplierID:     "SUP_XXXXX",
		Name:           "更新后的供应商名称",
		CorpID:         "dingXXXXXX",
		UserID:         "user123",
		ContactName:    "李四",
		ContactTelephone: "13900139000",
		ContactEmail:   "new@supplier.com",
		Description:    "长期合作供应商",
	}

	bizDataBytes, _ := json.Marshal(bizData)

	req := &UpdateSupplierRequest{
		InvokeID: "invoke_003",
		UserID:   "user123",
		Data:     string(bizDataBytes),
		BizType:  "update_supplier",
	}

	resp, err := client.UpdateSupplier(context.Background(), req)
	if err != nil {
		log.Fatalf("更新供应商失败: %v", err)
	}

	fmt.Printf("更新供应商响应: invokeId=%s, bizType=%s\n", resp.InvokeID, resp.BizType)
}

// ExampleClient_QuerySupplierByUserDefineCode 展示了如何根据自定义编码查询供应商
func ExampleClient_QuerySupplierByUserDefineCode() {
	client := NewClient(
		"https://api.example.com",
		"your-tenant-id",
		"dd-ai-table",
		"your-client-secret",
	)

	bizData := QuerySupplierByUserDefineCodeBizData{
		CorpID:         "dingXXXXXX",
		UserDefineCode: "SUP-001",
	}

	bizDataBytes, _ := json.Marshal(bizData)

	req := &QuerySupplierByUserDefineCodeRequest{
		InvokeID: "invoke_004",
		UserID:   "user123",
		Data:     string(bizDataBytes),
		BizType:  "query_supplier_by_userDefineCode",
	}

	resp, err := client.QuerySupplierByUserDefineCode(context.Background(), req)
	if err != nil {
		log.Fatalf("查询供应商失败: %v", err)
	}

	fmt.Printf("查询供应商响应: invokeId=%s, bizType=%s\n", resp.InvokeID, resp.BizType)
}

=== SDK 生成完成 ===