1322 lines
45 KiB
Markdown
1322 lines
45 KiB
Markdown
// 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
|
||
|
||
import "encoding/json"
|
||
|
||
// ============================================================
|
||
// 通用请求/响应结构
|
||
// ============================================================
|
||
|
||
// CommonResponse 通用API响应结构
|
||
type CommonResponse struct {
|
||
Code int `json:"code"`
|
||
Msg string `json:"msg,omitempty"`
|
||
Data json.RawMessage `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 json.RawMessage `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 json.RawMessage `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 json.RawMessage `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 json.RawMessage `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)
|
||
}
|
||
|
||
// 如果response不为nil,将commonResp.Data反序列化到response
|
||
if response != nil {
|
||
if err := json.Unmarshal(commonResp.Data, 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
|
||
// 注意:平台回调时,请求体为 NotificationRequest 结构,其中 Data 字段为 PaymentNotification 的JSON字符串
|
||
func HandlePaymentNotification(body []byte) (string, error) {
|
||
// 先解析外层通知结构
|
||
var notificationReq NotificationRequest
|
||
if err := json.Unmarshal(body, ¬ificationReq); err != nil {
|
||
return "FAILED", NewSDKError(ErrCodeInvalidParam, "解析通知请求失败", err)
|
||
}
|
||
|
||
// 根据bizType处理不同业务
|
||
switch notificationReq.BizType {
|
||
case "payment_notification":
|
||
// 解析内部支付通知数据
|
||
var paymentNotification PaymentNotification
|
||
if err := json.Unmarshal([]byte(notificationReq.Data), &paymentNotification); err != nil {
|
||
return "FAILED", NewSDKError(ErrCodeInvalidParam, "解析支付通知数据失败", err)
|
||
}
|
||
// 业务处理由调用方自行实现,此处仅返回成功
|
||
// 调用方应在此函数基础上扩展业务逻辑
|
||
_ = paymentNotification
|
||
default:
|
||
// 未知业务类型,记录日志后返回失败
|
||
return "FAILED", NewSDKError(ErrCodeInvalidParam, "未知业务类型: "+notificationReq.BizType, nil)
|
||
}
|
||
|
||
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() {
|
||
// 模拟平台回调的请求体(符合NotificationRequest格式)
|
||
notificationBody := `{
|
||
"bizType": "payment_notification",
|
||
"bizId": "instance_001",
|
||
"data": "{\"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 notificationReq NotificationRequest
|
||
json.Unmarshal([]byte(notificationBody), ¬ificationReq)
|
||
var paymentNotification PaymentNotification
|
||
json.Unmarshal([]byte(notificationReq.Data), &paymentNotification)
|
||
fmt.Printf("收到支付通知: 单据编码=%s, 支付状态=%s\n", paymentNotification.Code, paymentNotification.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)
|
||
// 如果需要解析响应数据,可以进一步处理 resp.Data
|
||
var responseData CreateSupplierResponseData
|
||
if err := json.Unmarshal(resp.Data, &responseData); err == nil {
|
||
fmt.Printf("响应数据: success=%v, result=%s\n", responseData.Success, responseData.Result)
|
||
}
|
||
}
|
||
|
||
// 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)
|
||
// 解析响应数据
|
||
var results []QuerySupplierByNameResult
|
||
if err := json.Unmarshal(resp.Data, &results); err == nil {
|
||
for _, r := range results {
|
||
fmt.Printf("供应商: %s, ID: %s\n", r.SupplierName, r.SupplierID)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 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)
|
||
// 解析响应数据
|
||
var responseData QuerySupplierByUserDefineCodeResponseData
|
||
if err := json.Unmarshal(resp.Data, &responseData); err == nil {
|
||
fmt.Printf("响应数据: success=%v\n", responseData.Success)
|
||
}
|
||
} |