first commit

menu v0.0.01
maguodong 2025-10-09 15:56:47 +08:00
commit ccd273840a
32 changed files with 2020 additions and 0 deletions

8
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="com.github.oldmegit.goframehelper.ui.goframehelperCache">
<option name="gf" value="true" />
</component>
</project>

9
.idea/lklSDK.iml Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

8
.idea/modules.xml Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/lklSDK.iml" filepath="$PROJECT_DIR$/.idea/lklSDK.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

259
README.md Normal file
View File

@ -0,0 +1,259 @@
# 拉卡拉SDK
这是一个通用的拉卡拉SDK提供了分账、交易、账户等功能的API接口封装方便开发者快速集成拉卡拉支付服务。
## 目录结构
```
lklsdk/
├── client.go # 核心客户端
├── split_ledger.go # 分账基本功能
├── split_ledger_more.go # 分账扩展功能
├── trade.go # 交易相关功能
├── account.go # 账户相关功能
├── merge_pre.go # 主扫合单交易功能
└── sdk.go # SDK主入口
```
## 安装
```bash
# 将SDK引入到您的项目中
go get -u github.com/black1552/lkl_sdk/lklsdk
```
## 快速开始
### 初始化SDK
```go
import (
"github.com/black1552/lkl_sdk/lklsdk"
"github.com/black1552/lkl_sdk/model"
"github.com/gogf/gf/v2/os/gctx"
)
// 创建配置
config := &lklsdk.Config{
AppID: "your_app_id", // 拉卡拉分配的AppID
TermNo: "your_term_no", // 终端号
MerchantNo: "your_merchant_no", // 商户号
SettleMerNo: "your_settle_mer_no", // 结算商户号
SettleTermNo: "your_settle_term_no", // 结算终端号
AccountType: "WECHAT", // 账户类型如WECHAT、ALIPAY等
TransType: "71", // 交易类型
Version: "3.0", // API版本
NotifyURL: "your_notify_url", // 回调URL
SerialNo: "your_mch_api_key", // 商户API密钥
}
// 初始化SDK使用泛型指定响应类型
sdk := lklsdk.NewSDK[model.ResponseType](gctx.New(), config)
```
## 功能模块
### 1. 主扫合单交易
```go
// 初始化特定响应类型的SDK
sdk := lklsdk.NewSDK[model.MergePreorderResponse](gctx.New(), config)
// 准备拆单信息
outSplitInfo := []*model.OutSplitInfo{
{
OutSubTradeNo: "子交易流水号1",
MerchantNo: config.MerchantNo,
TermNo: config.TermNo,
Amount: "100", // 1元
},
{
OutSubTradeNo: "子交易流水号2",
MerchantNo: config.MerchantNo,
TermNo: config.TermNo,
Amount: "200", // 2元
},
}
// 构建位置信息
locationInfo := &model.LocationInfo{
RequestIp: "127.0.0.1",
}
// 构建请求参数
mergePreorderReq := &model.MergePreorderReqData{
MerchantNo: config.MerchantNo,
TermNo: config.TermNo,
OutTradeNo: "商户交易流水号",
OutSplitInfo: outSplitInfo,
AccountType: "WECHAT",
TransType: "71",
TotalAmount: "300", // 3元
LocationInfo: locationInfo,
Subject: "测试订单",
NotifyUrl: "https://your-notify-url.com",
}
// 调用接口
mergePreorderResp, err := sdk.MergePreOrder(mergePreorderReq)
if err != nil {
log.Printf("主扫合单交易失败: %v\n", err)
}
// 使用SuccessOrFail方法判断请求是否成功
if !mergePreorderResp.SuccessOrFail() {
log.Printf("主扫合单交易失败: %s\n", mergePreorderResp.Msg)
}
```
### 2. 商户分账业务开通申请
```go
// 初始化特定响应类型的SDK
sdk := lklsdk.NewSDK[model.ApplyLedgerMerResponse](gctx.New(), config)
// 构建请求参数
applyLedgerReq := &model.ApplyLedgerMerReqData{
Version: "1.0",
OrderNo: "12345678901234567890123456789012", // 32位订单号
OrgCode: "123456789012", // 机构代码
MerInnerNo: "1234567821", // 拉卡拉内部商户号
MerCupNo: "", // 银联商户号(与内部商户号二选一)
ContactMobile: "13311111111", // 联系手机号
SplitLowestRatio: 3.51, // 最低分账比例
SplitEntrustFileName: "授权委托书.pdf", // 授权委托书文件名
SplitEntrustFilePath: "path", // 授权委托书文件路径
SplitRange: "ALL", // 分账范围ALL全部交易分账MARK标记交易分账
RetUrl: "notifyUrl.com", // 回调URL
}
// 调用接口
expectResp, err := sdk.ApplyLedgerMer(applyLedgerReq)
if err != nil {
log.Printf("商户分账业务开通申请失败: %v\n", err)
}
// 使用SuccessOrFail方法判断请求是否成功
if !expectResp.SuccessOrFail() {
log.Printf("商户分账业务开通申请失败: %s\n", expectResp.RetMsg)
}
```
### 3. 交易查询
```go
// 初始化特定响应类型的SDK
sdk := lklsdk.NewSDK[model.TradeQueryResponse](gctx.New(), config)
// 构建请求参数
tradeQueryReq := &model.TradeQueryReqData{
MerchantNo: config.MerchantNo,
TermNo: config.TermNo,
OutTradeNo: "商户订单号", // 替换为实际的商户订单号
}
// 调用接口
tradeQueryResp, err := sdk.TradeQuery(tradeQueryReq)
if err != nil {
log.Printf("交易查询失败: %v\n", err)
}
// 使用SuccessOrFail方法判断请求是否成功
if !tradeQueryResp.SuccessOrFail() {
log.Printf("交易查询失败: %s\n", tradeQueryResp.Msg)
}
```
### 4. 订单分账
```go
// 初始化特定响应类型的SDK
sdk := lklsdk.NewSDK[model.OrderSplitLedgerResponse](gctx.New(), config)
// 准备分账接收方数据
var recvDatas []*model.OrderSplitLedgerRecvDatas
// 可以向recvDatas数组中添加分账接收方信息
// 构建请求参数
splitLedgerReq := &model.OrderSplitLedgerReqData{
MerchantNo: config.MerchantNo,
LogDate: "", // 交易日期格式为yyyyMMdd
LogNo: "", // 拉卡拉对账单流水号
OutSeparateNo: "", // 商户分账指令流水号
TotalAmt: "", // 分账总金额,单位为分
LklOrgNo: "", // 拉卡拉机构编号
CalType: "", // 分账计算类型0-按金额1-按比例)
NotifyUrl: "", // 回调地址
RecvDatas: recvDatas, // 分账接收方数据
}
// 调用接口
splitLedgerResp, err := sdk.OrderSplitLedger(splitLedgerReq)
if err != nil {
log.Printf("订单分账失败: %v\n", err)
}
// 使用SuccessOrFail方法判断请求是否成功
if !splitLedgerResp.SuccessOrFail() {
log.Printf("订单分账失败: %s\n", splitLedgerResp.Msg)
}
```
### 5. 账户余额查询
```go
// 初始化特定响应类型的SDK
sdk := lklsdk.NewSDK[model.BalanceQueryResponse](gctx.New(), config)
// 构建请求参数
balanceQueryReq := &model.BalanceQueryReqData{
MerchantNo: config.MerchantNo,
OrgNo: "", // 机构号
PayNo: "", // 支付单号
PayType: "", // 支付类型
MgtFlag: "", // 管理标志
}
// 调用接口
balanceQueryResp, err := sdk.BalanceQuery(balanceQueryReq)
if err != nil {
log.Printf("账户余额查询失败: %v\n", err)
}
// 使用SuccessOrFail方法判断请求是否成功
if !balanceQueryResp.SuccessOrFail() {
log.Printf("账户余额查询失败: %s\n", balanceQueryResp.Msg)
}
```
## 错误处理
SDK使用两层错误处理机制请确保同时检查网络错误和业务响应状态
```go
// 1. 首先检查网络或SDK层面的错误
resp, err := sdk.SomeFunction(req)
if err != nil {
log.Printf("调用接口失败: %v\n", err)
// 处理网络错误或SDK内部错误
return err
}
// 2. 然后使用SuccessOrFail()方法判断业务响应是否成功
if !resp.SuccessOrFail() {
log.Printf("业务处理失败: %s\n", resp.Msg) // 或resp.RetMsg
// 处理业务失败情况
return errors.New("业务处理失败")
}
// 处理成功响应
// 使用resp获取返回的数据
```
## 注意事项
1. 请妥善保管您的AppID、商户号、密钥等敏感信息
2. 确保网络环境稳定,避免请求超时
3. 建议添加请求重试机制,处理网络波动
4. 请遵循拉卡拉的接口规范,不要频繁调用接口
5. 如遇到问题,请参考拉卡拉官方文档或联系技术支持

34
consts/url.go Normal file
View File

@ -0,0 +1,34 @@
package consts
const (
BASE_URL = "https://s2.lakala.com/api"
)
const (
// LKL_UPLOAD_FILE_URL 拉卡拉附件上传地址
LKL_UPLOAD_FILE_URL = "/v2/mms/openApi/uploadFile"
// LKL_SPLIT_LEDGER_URL 拉卡拉商户分账业务开通申请
LKL_SPLIT_LEDGER_URL = "/v2/mms/openApi/ledger/applyLedgerMer"
// LKL_SPLIT_LEDGER_QUERY_URL 拉卡拉商户分账信息查询
LKL_SPLIT_LEDGER_QUERY_URL = "/v2/mms/openApi/ledger/queryLedgerMer"
// LKL_SPLIT_LEDGER_RECEIVE_URL 拉卡拉分账接收方创建申请
LKL_SPLIT_LEDGER_RECEIVE_URL = "/v2/mms/openApi/ledger/applyLedgerReceiver"
// LKL_SPLIT_LEDGER_RECEIVE_BIND_URL 拉卡拉分账关系绑定申请
LKL_SPLIT_LEDGER_RECEIVE_BIND_URL = "/v2/mms/openApi/ledger/applyBind"
// LKL_SPLIT_LEDGER_BALANCE_URL 拉卡拉可分账金额查询
LKL_SPLIT_LEDGER_BALANCE_URL = "/v3/sacs/queryAmt"
// LKL_ORDER_SPLIT_LEDGER_URL 拉卡拉订单分账
LKL_ORDER_SPLIT_LEDGER_URL = "/v3/sacs/separate"
// LKL_ACCOUNT_BALANCE_QUERY_URL 拉卡拉账户余额查询
LKL_ACCOUNT_BALANCE_QUERY_URL = "/v2/laep/industry/ewalletBalanceQuery"
// LKL_ACCOUNT_WITHDRAW_URL 拉卡拉账户提现
LKL_ACCOUNT_WITHDRAW_URL = "/v2/laep/industry/ewalletWithdrawD1"
// LKL_TRADE_QUERY_URL 拉卡拉交易查询
LKL_TRADE_QUERY_URL = "/v3/labs/query/tradequery"
// LKL_PRE_ORDER_URL 拉卡拉聚合预下单
LKL_PRE_ORDER_URL = "/v3/labs/trans/preorder"
// LKL_MERGE_ORDER_URL 拉卡拉主扫合单交易
LKL_MERGE_ORDER_URL = "/v3/labs/trans/merge/preorder"
// LKL_REFOUND_URL 拉卡拉退款
LKL_REFOUND_URL = "/v3/rfd/refund_front/refund"
)

43
go.mod Normal file
View File

@ -0,0 +1,43 @@
module github.com/black1552/lkl_sdk
go 1.24.3
toolchain go1.24.7
require (
github.com/black1552/base-common v1.0.93
github.com/gogf/gf/v2 v2.9.3
)
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/BurntSushi/toml v1.5.0 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sql-driver/mysql v1.9.2 // indirect
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.3 // indirect
github.com/gorilla/websocket v1.5.3 // indirect
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/olekukonko/errors v1.1.0 // indirect
github.com/olekukonko/ll v0.0.9 // indirect
github.com/olekukonko/tablewriter v1.0.9 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.37.0 // indirect
go.opentelemetry.io/otel/metric v1.37.0 // indirect
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
go.opentelemetry.io/otel/trace v1.37.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

88
go.sum Normal file
View File

@ -0,0 +1,88 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/black1552/base-common v1.0.93 h1:wyWVmXL8YpzMOzyhyZaOzPzakA2iKBAUu6ZyjTNe6XA=
github.com/black1552/base-common v1.0.93/go.mod h1:SNRCsxP8d0itcZa0ZGCnNNRGdsxQ5tWc2h6GlobFkrs=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.9.2 h1:4cNKDYQ1I84SXslGddlsrMhc8k4LeDVj6Ad6WRjiHuU=
github.com/go-sql-driver/mysql v1.9.2/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.3 h1:P4jrnp+Vmh3kDeaH/kyHPI6rfoMmQD+sPJa716aMbS0=
github.com/gogf/gf/contrib/drivers/mysql/v2 v2.9.3/go.mod h1:yEhfx78wgpxUJhH9C9bWJ7I3JLcVCzUg11A4ORYTKeg=
github.com/gogf/gf/v2 v2.9.3 h1:qjN4s55FfUzxZ1AE8vUHNDX3V0eIOUGXhF2DjRTVZQ4=
github.com/gogf/gf/v2 v2.9.3/go.mod h1:w6rcfD13SmO7FKI80k9LSLiSMGqpMYp50Nfkrrc2sEE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

60
lklsdk/account.go Normal file
View File

@ -0,0 +1,60 @@
package lklsdk
import (
"time"
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
)
// AccountService 账户服务
type AccountService[T any] struct {
client *Client[T]
}
// NewAccountService 创建账户服务实例
func NewAccountService[T any](client *Client[T]) *AccountService[T] {
return &AccountService[T]{
client: client,
}
}
// BalanceQuery 账户余额查询
func (a *AccountService[T]) BalanceQuery(req *model.BalanceQueryReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_ACCOUNT_BALANCE_QUERY_URL
// 构建BaseModel请求
baseReq := model.BalanceQueryRequest{
ReqTime: time.Now().Format("20060102150405"),
Version: "3.0",
ReqData: req,
}
// 发送请求
respBody, err := a.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// Withdraw 账户提现
func (a *AccountService[T]) Withdraw(req *model.WithdrawReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_ACCOUNT_WITHDRAW_URL
// 构建BaseModel请求
baseReq := model.WithdrawRequest{
ReqTime: time.Now().Format("20060102150405"),
Version: "3.0",
ReqData: req,
}
// 发送请求
respBody, err := a.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

122
lklsdk/client.go Normal file
View File

@ -0,0 +1,122 @@
package lklsdk
import (
"context"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
ran "math/rand"
"time"
"github.com/black1552/base-common/utils"
"github.com/gogf/gf/v2/os/gfile"
)
// Config 拉卡拉SDK配置
type Config struct {
AppID string `json:"app_id"`
TermNo string `json:"term_no"`
MerchantNo string `json:"merchant_no"`
SettleMerNo string `json:"settle_merchant_no"`
SettleTermNo string `json:"settle_term_no"`
AccountType string `json:"account_type"`
TransType string `json:"trans_type"`
Version string `json:"version"`
NotifyURL string `json:"notify_url"`
PublicKey string `json:"public_key"`
PrivateKey string `json:"private_key"`
SerialNo string `json:"serial_no"`
}
// Client 拉卡拉SDK客户端
type Client[T any] struct {
config *Config
response T
ctx context.Context
}
// NewClient 创建拉卡拉SDK客户端
func NewClient[T any](ctx context.Context, config *Config) *Client[T] {
return &Client[T]{
config: config,
ctx: ctx,
}
}
func (c *Client[T]) generateNonceStr() string {
const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789"
nonce := make([]byte, 12)
for i := range nonce {
nonce[i] = letterBytes[ran.Intn(len(letterBytes))]
}
return string(nonce)
}
// generateSign 生成签名
func (c *Client[T]) generateSign(request []byte) (string, error) {
// 生成随机字符串
nonceStr := c.generateNonceStr()
// 获取当前时间戳(秒)
timestamp := fmt.Sprintf("%d", time.Now().Unix())
// 构建待签名报文
signData := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", c.config.AppID, c.config.SerialNo, timestamp, nonceStr, string(request))
// 计算签名
hashed := sha256.Sum256([]byte(signData))
privateKey, err := c.loadPrivateKey()
if err != nil {
return "", err
}
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hashed[:])
if err != nil {
return "", err
}
signatureBase64 := base64.StdEncoding.EncodeToString(signature)
// 构建Authorization头
authorization := fmt.Sprintf("LKLAPI-SHA256withRSA appid=\"%s\",serial_no=\"%s\",timestamp=\"%s\",nonce_str=\"%s\",signature=\"%s\"",
c.config.AppID, c.config.SerialNo, timestamp, nonceStr, signatureBase64)
return authorization, nil
}
func (c *Client[T]) loadPrivateKey() (*rsa.PrivateKey, error) {
block, _ := pem.Decode(gfile.GetBytes(c.config.PrivateKey))
if block == nil {
return nil, fmt.Errorf("无法解码私钥PEM数据")
}
// 解析PKCS#8格式私钥
privateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return privateKey.(*rsa.PrivateKey), nil
}
// doRequest 发送HTTP请求
func (c *Client[T]) doRequest(url string, reqData interface{}) (*T, error) {
// 序列化为JSON
jsonData, err := json.Marshal(reqData)
if err != nil {
return nil, fmt.Errorf("序列化请求数据失败: %v", err)
}
auth, err := c.generateSign(jsonData)
if err != nil {
return nil, fmt.Errorf("生成签名失败: %v", err)
}
header := map[string]string{
"Authorization": auth,
"Content-Type": "application/json",
"Accept": "application/json",
}
// 设置其他必要的请求头
return utils.NewClient[T](jsonData, url, header).Post(c.ctx)
}

38
lklsdk/mergePre.go Normal file
View File

@ -0,0 +1,38 @@
package lklsdk
import (
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
"github.com/gogf/gf/v2/os/gtime"
)
type MergePreService[T any] struct {
client *Client[T]
}
// NewMergePreService 创建拉卡拉主扫合单交易
func NewMergePreService[T any](client *Client[T]) *MergePreService[T] {
return &MergePreService[T]{
client: client,
}
}
func (s *MergePreService[T]) PreOrder(req *model.MergePreorderReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_MERGE_ORDER_URL
// 构建BaseModel请求
baseReq := model.MergePreorder{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "2.0",
ReqData: req,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

96
lklsdk/sdk.go Normal file
View File

@ -0,0 +1,96 @@
package lklsdk
import (
"context"
"github.com/black1552/lkl_sdk/model"
)
// SDK 拉卡拉SDK主入口
type SDK[T any] struct {
Client *Client[T]
SplitLedger *SplitLedgerService[T]
Trade *TradeService[T]
Account *AccountService[T]
UploadFile *UploadFileService[T]
MergePre *MergePreService[T]
}
// NewSDK 创建拉卡拉SDK实例
func NewSDK[T any](ctx context.Context, config *Config) *SDK[T] {
client := NewClient[T](ctx, config)
return &SDK[T]{
Client: client,
SplitLedger: NewSplitLedgerService(client),
Trade: NewTradeService(client),
Account: NewAccountService(client),
UploadFile: NewUploadFileService(client),
MergePre: NewMergePreService(client),
}
}
// 以下为便捷方法直接通过SDK调用各服务的主要功能
// MergePreOrder 主扫合单交易
func (s *SDK[T]) MergePreOrder(req *model.MergePreorderReqData) (*T, error) {
return s.MergePre.PreOrder(req)
}
// Refound 退款
func (s *SDK[T]) Refound(req *model.RefundReqData) (*T, error) {
return s.Trade.Refound(req)
}
// ApplyLedgerMer 商户分账业务开通申请
func (s *SDK[T]) ApplyLedgerMer(req *model.ApplyLedgerMerReqData) (*T, error) {
return s.SplitLedger.ApplyLedgerMer(req)
}
// QueryLedgerMer 商户分账信息查询
func (s *SDK[T]) QueryLedgerMer(req *model.QueryLedgerMerReqData) (*T, error) {
return s.SplitLedger.QueryLedgerMer(req)
}
// ApplyLedgerReceiver 分账接收方创建申请
func (s *SDK[T]) ApplyLedgerReceiver(req *model.ApplyLedgerReceiverReqData) (*T, error) {
return s.SplitLedger.ApplyLedgerReceiver(req)
}
// ApplyBind 分账关系绑定申请
func (s *SDK[T]) ApplyBind(req *model.ApplyBindReqData) (*T, error) {
return s.SplitLedger.ApplyBind(req)
}
// QuerySplitBalance 可分账金额查询
func (s *SDK[T]) QuerySplitBalance(req *model.SplitBalanceReqData) (*T, error) {
return s.SplitLedger.QuerySplitBalance(req)
}
// OrderSplitLedger 订单分账
func (s *SDK[T]) OrderSplitLedger(req *model.OrderSplitLedgerReqData) (*T, error) {
return s.SplitLedger.OrderSplitLedger(req)
}
// TradeQuery 交易查询
func (s *SDK[T]) TradeQuery(req *model.TradeQueryReqData) (*T, error) {
return s.Trade.TradeQuery(req)
}
// PreOrder 聚合预下单
func (s *SDK[T]) PreOrder(req *model.PreorderReqData) (*T, error) {
return s.Trade.PreOrder(req)
}
// BalanceQuery 账户余额查询
func (s *SDK[T]) BalanceQuery(req *model.BalanceQueryReqData) (*T, error) {
return s.Account.BalanceQuery(req)
}
func (s *SDK[T]) UploadFileQuery(req *model.UploadFileReqData) (*T, error) {
return s.UploadFile.UploadFileQuery(req)
}
// Withdraw 账户提现
func (s *SDK[T]) Withdraw(req *model.WithdrawReqData) (*T, error) {
return s.Account.Withdraw(req)
}

97
lklsdk/split_ledger.go Normal file
View File

@ -0,0 +1,97 @@
package lklsdk
import (
"fmt"
"time"
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
// SplitLedgerService 分账服务
type SplitLedgerService[T any] struct {
client *Client[T]
}
// NewSplitLedgerService 创建分账服务实例
func NewSplitLedgerService[T any](client *Client[T]) *SplitLedgerService[T] {
return &SplitLedgerService[T]{
client: client,
}
}
// ApplyLedgerMer 商户分账业务开通申请
func (s *SplitLedgerService[T]) ApplyLedgerMer(req *model.ApplyLedgerMerReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_SPLIT_LEDGER_URL
md5, err := gmd5.Encrypt(gconv.String(time.Now().Unix()))
if err != nil {
return nil, fmt.Errorf("创建ReqId失败")
}
// 构建BaseModel请求
baseReq := model.ApplyLedgerMerRequest{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "2.0",
ReqData: req,
ReqId: md5,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// ApplyLedgerReceiver 分账接收方创建申请
func (s *SplitLedgerService[T]) ApplyLedgerReceiver(req *model.ApplyLedgerReceiverReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_SPLIT_LEDGER_RECEIVE_URL
md5, err := gmd5.Encrypt(gconv.String(time.Now().Unix()))
if err != nil {
return nil, fmt.Errorf("创建ReqId失败")
}
// 构建BaseModel请求
baseReq := model.ApplyLedgerReceiverRequest{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "2.0",
ReqId: md5,
ReqData: req,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// QueryLedgerMer 商户分账信息查询
func (s *SplitLedgerService[T]) QueryLedgerMer(req *model.QueryLedgerMerReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_SPLIT_LEDGER_QUERY_URL
// 构建BaseModel请求
baseReq := model.QueryLedgerMerRequest{
ReqTime: time.Now().Format("20060102150405"),
Version: "3.0",
ReqData: req,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

View File

@ -0,0 +1,77 @@
package lklsdk
import (
"fmt"
"time"
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
)
// ApplyBind 分账关系绑定申请
func (s *SplitLedgerService[T]) ApplyBind(req *model.ApplyBindReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_SPLIT_LEDGER_RECEIVE_BIND_URL
md5, err := gmd5.Encrypt(gconv.String(time.Now().Unix()))
if err != nil {
return nil, fmt.Errorf("创建ReqId失败")
}
// 构建BaseModel请求
baseReq := model.ApplyBindRequest{
ReqTime: time.Now().Format("20060102150405"),
Version: "2.0",
ReqData: req,
ReqId: md5,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// QuerySplitBalance 可分账金额查询
func (s *SplitLedgerService[T]) QuerySplitBalance(req *model.SplitBalanceReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_SPLIT_LEDGER_BALANCE_URL
// 构建BaseModel请求
baseReq := model.SplitBalanceRequest{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "3.0",
ReqData: req,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// OrderSplitLedger 订单分账
func (s *SplitLedgerService[T]) OrderSplitLedger(req *model.OrderSplitLedgerReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_ORDER_SPLIT_LEDGER_URL
// 构建BaseModel请求
baseReq := model.OrderSplitLedgerRequest{
ReqTime: time.Now().Format("20060102150405"),
Version: "3.0",
ReqData: req,
}
// 发送请求
respBody, err := s.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

74
lklsdk/trade.go Normal file
View File

@ -0,0 +1,74 @@
package lklsdk
import (
"time"
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
)
// TradeService 交易服务
type TradeService[T any] struct {
client *Client[T]
}
// NewTradeService 创建交易服务实例
func NewTradeService[T any](client *Client[T]) *TradeService[T] {
return &TradeService[T]{
client: client,
}
}
// TradeQuery 交易查询
func (t *TradeService[T]) TradeQuery(req *model.TradeQueryReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_TRADE_QUERY_URL
// 构建BaseModel请求
baseReq := model.TradeQuery{
ReqTime: time.Now().Format("20060102150405"),
Version: "3.0",
OutOrgCode: t.client.config.AppID,
ReqData: req,
}
// 发送请求
respBody, err := t.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// PreOrder 聚合预下单
func (t *TradeService[T]) PreOrder(req *model.PreorderReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_PRE_ORDER_URL
// 构建BaseModel请求
baseReq := model.NewPreorder(req)
// 发送请求
respBody, err := t.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}
// Refound 退款
func (t *TradeService[T]) Refound(req *model.RefundReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_REFOUND_URL
// 构建BaseModel请求
baseReq := model.NewRefund(req)
// 发送请求
respBody, err := t.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

47
lklsdk/uploadFile.go Normal file
View File

@ -0,0 +1,47 @@
package lklsdk
import (
"fmt"
"time"
"github.com/black1552/lkl_sdk/consts"
"github.com/black1552/lkl_sdk/model"
"github.com/gogf/gf/v2/crypto/gmd5"
"github.com/gogf/gf/v2/util/gconv"
)
// UploadFileService 交易服务
type UploadFileService[T any] struct {
client *Client[T]
}
// NewUploadFileService 创建交易服务实例
func NewUploadFileService[T any](client *Client[T]) *UploadFileService[T] {
return &UploadFileService[T]{
client: client,
}
}
// UploadFileQuery 交易查询
func (t *UploadFileService[T]) UploadFileQuery(req *model.UploadFileReqData) (*T, error) {
// 构建请求参数
url := consts.BASE_URL + consts.LKL_UPLOAD_FILE_URL
md5, err := gmd5.Encrypt(gconv.String(time.Now().Unix()))
if err != nil {
return nil, fmt.Errorf("创建ReqId失败")
}
// 构建BaseModel请求
baseReq := model.UploadFileRequest{
Timestamp: gconv.String(time.Now().Unix()),
Ver: "1.0",
ReqId: md5,
ReqData: req,
}
// 发送请求
respBody, err := t.client.doRequest(url, baseReq)
if err != nil {
return nil, err
}
return respBody, nil
}

50
model/applyBind.go Normal file
View File

@ -0,0 +1,50 @@
package model
// ApplyBindRequest 分账关系绑定请求结构体
// 用于发起分账接收方与商户的关系绑定申请
// 拉卡拉SDK接口文档分账关系绑定接口
type ApplyBindRequest struct {
ReqData *ApplyBindReqData `json:"reqData"` // 请求业务数据
ReqId string `json:"reqId"` // 请求ID唯一标识一笔请求
Version string `json:"version"` // 接口版本号
ReqTime string `json:"reqTime"` // 请求时间格式为yyyyMMddHHmmss
}
// ApplyBindReqData 分账关系绑定请求业务数据结构体
// 包含分账关系绑定所需的详细业务参数
type ApplyBindReqData struct {
Version string `json:"version"` // 接口版本号必传长度8取值说明1.0
OrderNo string `json:"orderNo"` // 订单编号必传长度32用于后续跟踪排查问题及核对报文格式为14位年月日(24小时制)分秒+8位随机数不重复
OrgCode string `json:"orgCode"` // 分账接收方所属机构代码必传长度32
MerInnerNo string `json:"merInnerNo"` // 分账商户内部商户号必传长度32与MerCupNo选传其一不能都为空
MerCupNo string `json:"merCupNo"` // 分账商户银联商户号必传长度32与MerInnerNo选传其一不能都为空
ReceiverNo string `json:"receiverNo"` // 分账接收方编号必传长度32
EntrustFileName string `json:"entrustFileName"` // 合作协议附件名称必传长度32
EntrustFilePath string `json:"entrustFilePath"` // 合作协议附件路径必传长度32通过调用附件上传接口获取
RetUrl string `json:"retUrl"` // 回调通知地址必传长度128审核通过后通知地址
Attachments []struct {
AttachType string `json:"attachType"` // 附件类型编码必传长度32
AttachName string `json:"attachName"` // 附件名称必传长度32
AttachStorePath string `json:"attachStorePath"` // 附件路径必传长度128通过调用附件上传接口获取
} `json:"attachments,omitempty"` // 附加资料,可选,集合类型,其他附加资料文件信息
}
// ApplyBindResponse 分账关系绑定响应结构体
// 包含分账关系绑定申请的处理结果信息
type ApplyBindResponse struct {
RetCode string `json:"retCode"` // 响应码000000表示成功
RetMsg string `json:"retMsg"` // 响应消息,描述响应结果
RespData struct {
Version string `json:"version"` // 接口版本号例如547110502170558464
OrderNo string `json:"orderNo"` // 订单编号例如2021020112000012345678
OrgCode string `json:"orgCode"` // 机构代码例如200669
ApplyId int64 `json:"applyId"` // 受理编号例如548099616395186176
} `json:"respData"` // 响应业务数据当retCode为000000时返回
}
func (a *ApplyBindResponse) SuccessOrFail() bool {
return a.RetCode == "000000"
}

50
model/applyLedgerMer.go Normal file
View File

@ -0,0 +1,50 @@
package model
// ApplyLedgerMerRequest 商户分账业务开通申请请求结构体
type ApplyLedgerMerRequest struct {
ReqData *ApplyLedgerMerReqData `json:"reqData"` // 请求业务数据
ReqId string `json:"reqId"` // 请求ID
Version string `json:"version"` // 接口版本号
ReqTime string `json:"reqTime"` // 请求时间
}
// ApplyLedgerMerReqData 商户分账业务开通申请请求业务数据结构体
type ApplyLedgerMerReqData struct {
Version string `json:"version"` // 版本号必传长度8取值说明1.0
OrderNo string `json:"orderNo"` // 订单编号必传长度32用于后续处理查询及回调通知消息标识2014年月日时分秒毫秒组成
OrgCode string `json:"orgCode"` // 机构代码必传长度12
MerInnerNo string `json:"merInnerNo"` // 拉卡拉内部商户号可选长度32拉卡拉内部商户号和银联商户号必须传一个默认以内部商户号为准
MerCupNo string `json:"merCupNo"` // 银联商户号可选长度32拉卡拉内部商户号和银联商户号必须传一个默认以内部商户号为准
ContactMobile string `json:"contactMobile"` // 联系手机号必传长度32
SplitLowestRatio float64 `json:"splitLowestRatio"` // 最低分账比例必传长度12百分比支持2位精度取值范围70-70.50
SplitEntrustFileName string `json:"splitEntrustFileName"` // 分账授权委托书文件名称必传长度64文件格式pdf
SplitEntrustFilePath string `json:"splitEntrustFilePath"` // 分账授权委托书文件路径必传长度64调用附件上传接口获取
SplitRange string `json:"splitRange"` // 分账范围必传长度32取值说明ALL-全部交易分账(所有交易默认都分账)MARK-标记交易分账(只有带标记交易才分账,其余交易正常结算)
SplitFundSource string `json:"splitFundSource"` // 分账依据非必传长度32取值说明TRA-交易分账BAR-金额分账
ElecContractId string `json:"elecContractId"` // 电子合同编号非必传长度32收单已签约交易电子合同编号供审核人员复核使用
SplitLaunchMode string `json:"splitLaunchMode"` // 分账发起方式非必传长度32取值说明AUTO-自动触发分账POINTTRUE-指定规则分账MANUAL-手动分账
SettleType string `json:"settleType"` // 结算类型非必传长度32取值说明01-主扫现结02-复扫现结03-交易自动结算
SplitRuleSource string `json:"splitRuleSource"` // 分账规则来源条件必传长度32取值说明MER-商户自定规则PLATFORM-平台分润规则(分润规则必传)
RetUrl string `json:"retUrl"` // 回调通知地址必传长度128分账申请结果以异步消息或同步返回的方式通知如需无线路由处理也可以通过第三方商户信息查询接口确定结算结果
Attachments []struct {
AttachType string `json:"attachType"` // 附件类型编码必传长度32
AttachName string `json:"attachName"` // 附件名称必传长度32
AttachStorePath string `json:"attachStorePath"` // 附件路径必传长度128调用附件上传接口获取
} `json:"attachments,omitempty"` // 附加资料,可选,集合,其他需附加的文件信息
}
// ApplyLedgerMerResponse 商户分账业务开通申请响应结构体
type ApplyLedgerMerResponse struct {
RetCode string `json:"retCode"` // 返回码000000表示成功
RetMsg string `json:"retMsg"` // 返回消息
RespData struct {
Version string `json:"version"` // 接口版本号例如547110502170558464
OrderNo string `json:"orderNo"` // 订单编号例如2021020112000012345678
OrgCode string `json:"orgCode"` // 机构代码例如200669
ApplyId int64 `json:"applyId"` // 受理编号例如548099616395186176
} `json:"respData"` // 响应数据
}
func (a *ApplyLedgerMerResponse) SuccessOrFail() bool {
return a.RetCode == "000000"
}

View File

@ -0,0 +1,104 @@
package model
// ApplyLedgerReceiverRequest 分账接收方创建请求结构体
// 用于向拉卡拉接口发送分账接收方创建请求
// 包含请求头信息和业务数据
type ApplyLedgerReceiverRequest struct {
// 请求业务数据
ReqData *ApplyLedgerReceiverReqData `json:"reqData"`
// 请求ID用于幂等性校验
ReqId string `json:"reqId"`
// 接口版本号
Version string `json:"version"`
// 请求时间格式为yyyyMMddHHmmss
ReqTime string `json:"reqTime"`
}
// ApplyLedgerReceiverReqData 分账接收方创建请求业务数据结构体
// 包含分账接收方创建所需的具体业务参数
// 用于创建分账接收方信息
type ApplyLedgerReceiverReqData struct {
// 接口版本号必传长度8取值说明1.0
Version string `json:"version"`
// 订单编号便于后续跟踪排查问题及核对报文必传长度32取值说明14位年月日24小时制分秒+8位的随机数不重复
OrderNo string `json:"orderNo"`
// 机构代码必传长度32
OrgCode string `json:"orgCode"`
// 分账接收方名称必传长度64
ReceiverName string `json:"receiverName"`
// 联系手机号必传长度16
ContactMobile string `json:"contactMobile"`
// 营业执照号码可选长度32取值说明收款账户类型为对公必须上送
LicenseNo string `json:"licenseNo"`
// 营业执照名称可选长度128取值说明收款账户类型为对公必须上送
LicenseName string `json:"licenseName"`
// 法人姓名可选长度32取值说明收款账户类型为对公必须上送
LegalPersonName string `json:"legalPersonName"`
// 法人证件类型可选长度32取值说明17身份证18护照19港澳居民来往内地通行证20台湾居民来往内地通行证收款账户类型为对公必须上送身份证外类型先咨询后再使用
LegalPersonCertificateType string `json:"legalPersonCertificateType"`
// 法人证件号可选长度32取值说明收款账户类型为对公必须上送
LegalPersonCertificateNo string `json:"legalPersonCertificateNo"`
// 收款账户卡号必传长度32
AcctNo string `json:"acctNo"`
// 收款账户名称必传长度32
AcctName string `json:"acctName"`
// 收款账户类型代码必传长度32取值说明57对公58对私
AcctTypeCode string `json:"acctTypeCode"`
// 收款账户证件类型必传长度32取值说明17身份证18护照19港澳居民来往内地通行证20台湾居民来往内地通行证身份证外类型先咨询后再使用
AcctCertificateType string `json:"acctCertificateType"`
// 收款账户证件号必传长度32
AcctCertificateNo string `json:"acctCertificateNo"`
// 收款账户开户行号必传长度32取值说明参照FBI.N信息查询仅支持对私结算账户
AcctOpenBankCode string `json:"acctOpenBankCode"`
// 收款账户开户行名称必传长度64取值说明参照FBI.N信息查询仅支持对私结算账户
AcctOpenBankName string `json:"acctOpenBankName"`
// 收款账户清算行行号必传长度32取值说明参照FBI.N信息查询仅支持对私结算账户
AcctClearBankCode string `json:"acctClearBankCode"`
// 接收方附件资料,可选,集合
AttachList []struct {
// 附件名称可选长度32
AttachName string `json:"attachName"`
// 附件路径可选长度32取值说明调用进件附件上传接口获取到附件路径
AttachStorePath string `json:"attachStorePath"`
// 附件类型编码可选长度32
AttachType string `json:"attachType"`
} `json:"attachList"`
// 提款类型可选长度32取值说明01主动提款03交易自动结算不填默认01
SettleType string `json:"settleType"`
}
// ApplyLedgerReceiverResponse 分账接收方创建响应结构体
// 拉卡拉接口返回的分账接收方创建响应数据
// 包含响应状态码、消息和业务数据
type ApplyLedgerReceiverResponse struct {
// 响应状态码000000表示成功
RetCode string `json:"retCode"`
// 响应消息
RetMsg string `json:"retMsg"`
// 响应业务数据当retCode为000000时返回
RespData *ApplyLedgerReceiverRespData `json:"respData"`
}
// ApplyLedgerReceiverRespData 分账接收方创建响应业务数据结构体
// 包含分账接收方创建返回的具体业务信息
type ApplyLedgerReceiverRespData struct {
// 接口版本号(回传)
Version string `json:"version"`
// 订单编号(回传)
OrderNo string `json:"orderNo"`
// 申请机构代码(回传)
OrgCode string `json:"orgCode"`
// 接收方所属机构
OrgId string `json:"orgId"`
// 接收方所属机构名称
OrgName string `json:"orgName"`
// 接收方编号
ReceiverNo string `json:"receiverNo"`
}
// SuccessOrFail 判断分账接收方创建请求是否成功
// 成功条件响应码为000000
// 返回值true表示成功false表示失败
func (resp *ApplyLedgerReceiverResponse) SuccessOrFail() bool {
return resp.RetCode == "000000"
}

67
model/balanceQuery.go Normal file
View File

@ -0,0 +1,67 @@
package model
// BalanceQueryRequest 余额查询请求结构体
// 用于向拉卡拉接口发送余额查询请求
// 包含请求头信息和业务数据
type BalanceQueryRequest struct {
// 请求业务数据
ReqData *BalanceQueryReqData `json:"req_data"`
// 接口版本号
Version string `json:"version"`
// 请求时间格式为yyyyMMddHHmmss
ReqTime string `json:"req_time"`
}
// BalanceQueryReqData 余额查询请求业务数据结构体
// 包含余额查询所需的具体业务参数
// 用于查询账户的实时余额信息
type BalanceQueryReqData struct {
// 机构号必传最大长度32
OrgNo string `json:"org_no"`
// 商户号或receiveNo或商户用户编号必传最大长度32
MerchantNo string `json:"merchant_no"`
// 账号若该参数上送则payType将无效非必传最大长度32
PayNo string `json:"pay_no"`
// 账号类型01收款账户02付款账户03分账商户账户04分账接收方账户05充值代付账户06结算代付账户-未上送则默认01非必传最大长度32
PayType string `json:"pay_type"`
// 账户标志01:一般账户;03:虚户)-未上送则默认01非必传最大长度32
MgtFlag string `json:"mgt_flag"`
}
// BalanceQueryResponse 余额查询响应结构体
// 拉卡拉接口返回的余额查询响应数据
// 包含响应状态码、消息和业务数据
type BalanceQueryResponse struct {
// 响应状态码000000
Code string `json:"code"`
// 响应消息
Msg string `json:"msg"`
// 响应业务数据当code为SACS0000时返回
RespData *BalanceQueryRespData `json:"resp_data"`
}
// BalanceQueryRespData 余额查询响应业务数据结构体
// 包含余额查询返回的具体账户信息
type BalanceQueryRespData struct {
// 账号,必传
PayNo string `json:"pay_no"`
// 账户类型,必传
PayType string `json:"pay_type"`
// 账户状态必传取值说明CLOSE销户NORMAL正常FREEZE冻结STOPAY止付
AcctSt string `json:"acct_st"`
// 预付余额(单位元),必传
ForceBalance string `json:"force_balance"`
// 上日余额(单位元)-该字段已废弃使用,必传
HisBalance string `json:"his_balance"`
// 实时余额(单位元),必传
ReBalance string `json:"re_balance"`
// 当前可用余额(单位元),必传
CuBalance string `json:"cu_balance"`
}
// SuccessOrFail 判断余额查询请求是否成功
// 成功条件响应码为SACS0000
// 返回值true表示成功false表示失败
func (resp *BalanceQueryResponse) SuccessOrFail() bool {
return resp.Code == "000000"
}

7
model/baseModel.go Normal file
View File

@ -0,0 +1,7 @@
package model
type BaseModel[T any] struct {
ReqTime string `json:"req_time"`
Version string `json:"version"`
ReqData T `json:"req_data"`
}

121
model/mergePreorder.go Normal file
View File

@ -0,0 +1,121 @@
package model
import "github.com/gogf/gf/v2/os/gtime"
// MergePreorder 主扫合单交易请求结构体
type MergePreorder struct {
ReqTime string `json:"req_time"` // 请求时间格式YYYYMMDDHHMMSS
Version string `json:"version"` // 接口版本号,固定值"3.0"
ReqData *MergePreorderReqData `json:"req_data"` // 请求业务数据
}
// MergePreorderReqData 主扫合单交易请求业务数据
type MergePreorderReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号拉卡拉分配的商户号String(32),必填
TermNo string `json:"term_no"` // 终端号拉卡拉分配的业务终端号String(32),必填
OutTradeNo string `json:"out_trade_no"` // 商户交易流水号商户系统唯一String(32),必填
OutSplitInfo []*OutSplitInfo `json:"out_split_info"` // 拆单信息List必填
AccountType string `json:"account_type"` // 钱包类型微信WECHAT 支付宝ALIPAY 银联UQRCODEPAY 京东钱包JDString(32),必填
TransType string `json:"trans_type"` // 接入方式41:NATIVE扫码支付(仅ALIPAY支持) 51:JSAPI微信公众号支付支付宝服务窗支付银联JS支付支付宝JS支付、拉卡拉钱包支付71:微信小程序支付 81:支付宝H5支付需特殊商户账户端支持String(2),必填
TotalAmount string `json:"total_amount"` // 金额单位分整数型字符String(12),必填
LocationInfo *LocationInfo `json:"location_info"` // 地址位置信息Object风控要求必送必填
BusiMode string `json:"busi_mode"` // 业务模式ACQ-收单 PAY-付款不填,默认为"ACQ-收单"String(8),选填
Subject string `json:"subject"` // 订单标题用于简单描述订单或商品主题传递给账户端账户端控制实际最多42个字节String(42),选填
NotifyUrl string `json:"notify_url"` // 商户通知地址,如果上传,且 pay_order_no 不存在情况下则按此地址通知商户String(128),选填
Remark string `json:"remark"` // 备注String(128),选填
IdentityInfo string `json:"identity_info"` // 实名支付信息json字符串如{"identityNo": "3200000000000000XX", "name": "张三"}然后国密sm2加密String(1024),选填
AccBusiFields *AccBusiFields `json:"acc_busi_fields"` // 账户端业务信息域Object选填
CompleteNotifyUrl string `json:"complete_notify_url"` // 发货确认通知地址发货类小程序确认收货后通知商户的地址String(128),选填
}
// OutSplitInfo 拆单信息
type OutSplitInfo struct {
OutSubTradeNo string `json:"out_sub_trade_no"` // 外部子交易流水号商户子交易流水号商户号下唯一String(32),必填
MerchantNo string `json:"merchant_no"` // 商户号拉卡拉分配的商户号String(32),必填
TermNo string `json:"term_no"` // 终端号拉卡拉分配的业务终端号String(32),必填
Amount string `json:"amount"` // 金额单位分整数型字符String(12),必填
SettleType string `json:"settle_type"` // 结算类型(单台),"0"或者空常规结算方式String(4),选填
SubRemark string `json:"sub_remark"` // 子备注子单备注信息String(64),选填
}
// LocationInfo 地址位置信息
type LocationInfo struct {
RequestIp string `json:"request_ip"` // 请求方IP地址请求方的IP地址存在必填格式如36.45.36.95String(64),必填
BaseStation string `json:"base_station"` // 基站信息客户端设备的基站信息主扫时基站信息使用该字段String(128),选填
Location string `json:"location"` // 维度,经度,商户终端的地理位置,存在必填格式:纬度,经度,+表示北纬、东经,-表示南纬、西经精度最长支持小数点后9位。举例:+37.123456789,121.123456789String(32),选填
}
// AccBusiFields 账户端业务信息域,微信主扫场景
type AccBusiFields struct {
TimeoutExpress string `json:"timeout_express"` // 预下单的订单的有效时间以分钟为单位。如果在有效时间内没有完成付款则在账户端该订单失效。如用户超时则账户端完成失效处理建议不超过15分钟。不传值则默认5分钟String(2),选填
SubAppId string `json:"sub_appid"` // 子商户公众账号IDsub_appid即微信小程序支付-71、公众号支付-51、微信支付-61此参数必传只对微信支付生效拉卡拉钱包情况下该字段上送LAKALA的openidString(32),选填
UserId string `json:"user_id"` // 用户标识用户在子商户sub_appid下的唯一标识sub_openid即微信小程序支付-71、公众号支付-51此参数必传只对微信支付有效String(64),选填
Detail string `json:"detail"` // 商品详情单品优惠功能字段详见下文说明String(1024),选填
GoodsTag string `json:"goods_tag"` // 订单优惠标记微信平台配置的商品标记用于优惠券或者满减使用accountType为WECHAT时可选填此字段String(32),选填
Attach string `json:"attach"` // 附加域附加数据在查询API和支付通知中原样返回该字段主要用于商户携带订单的自定义数据。商户定制字段直接送到账户端String(128),选填
GoodsDetail []*GoodsDetail `json:"goods_detail"` // 商品详情列表,微信商品详情字段说明
}
// GoodsDetail 微信商品详情字段说明
type GoodsDetail struct {
GoodsId string `json:"goods_id"` // 商品ID由半角的大小写字母、数字、中划线、下划线中的一种或几种组成。如"商品编码",必填
WxpayGoodsId string `json:"wxpay_goods_id"` // 微信支付定义的统一商品编号String(32),选填
GoodsName string `json:"goods_name"` // 商品的实际名称String(256),选填
Quantity string `json:"quantity"` // 用户购买的数量String(12),必填
Price string `json:"price"` // 单价单位为分。如果商户有优惠需传输商户优惠后的单价String(12),必填
}
// NewMergePreorder 创建主扫合单交易请求
func NewMergePreorder(param *MergePreorderReqData) *MergePreorder {
return &MergePreorder{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "3.0",
ReqData: param,
}
}
// MergePreorderResponse 主扫合单交易响应结构体
type MergePreorderResponse struct {
Code string `json:"code"` // 响应码BBS00000表示成功
Msg string `json:"msg"` // 响应信息,对响应码的文字描述
ReqData MergePreorderRespData `json:"resp_data"` // 响应业务数据
RespTime string `json:"resp_time"` // 响应时间
}
// MergePreorderRespData 主扫合单交易响应业务数据
type MergePreorderRespData struct {
MerchantNo string `json:"merchant_no"` // 商户号(待上线),拉卡拉分配的商户号(请求接口中商户号)
OutTradeNo string `json:"out_trade_no"` // 商户请求流水号,请求报文中的商户请求流水号
TradeNo string `json:"trade_no"` // 拉卡拉交易流水号
LogNo string `json:"log_no"` // 拉卡拉对账单流水号
SplitInfo []*SplitInfo `json:"split_info"` // 拆单信息
AccRespFields interface{} `json:"acc_resp_fields"` // 账户端返回信息域
}
// SplitInfo 拆单信息
type SplitInfo struct {
SubTradeNo string `json:"sub_trade_no"` // 子单交易流水号
SubLogNo string `json:"sub_log_no"` // 子单对账单流水号
OutSubTradeNo string `json:"out_sub_trade_no"` // 外部子交易流水号,商户子交易流水号,商户号下唯一
MerchantNo string `json:"merchant_no"` // 商户号,拉卡拉分配的商户号
MerchantName string `json:"merchant_name"` // 商户名称
TermNo string `json:"term_no"` // 终端号,拉卡拉分配的业务终端号
Amount string `json:"amount"` // 金额,单位为:分。整数型字符
}
// WxAccRespFields 微信(71-小程序/微信(51-JSAPI)场景下账户端返回信息域
type WxAccRespFields struct {
PrepayId string `json:"prepay_id"` // 预下单ID预支付交易会话ID
PaySign string `json:"pay_sign"` // 支付签名信息
AppId string `json:"app_id"` // 小程序ID商户注册具有支付权限的小程序成功后即可获得小程序ID
TimeStamp string `json:"time_stamp"` // 时间戳,当前的时间
NonceStr string `json:"nonce_str"` // 随机字符串
Package string `json:"package"` // 订单详情扩展字符串
SignType string `json:"sign_type"` // 签名方式签名类型支持RSA
SubMchId string `json:"sub_mch_id"` // 子商户号,账户端子商户号
}
// SuccessOrFail 判断主扫合单交易是否成功
func (m *MergePreorderResponse) SuccessOrFail() bool {
return m.Code == "BBS00000"
}

55
model/orderSplitLedger.go Normal file
View File

@ -0,0 +1,55 @@
package model
// OrderSplitLedgerRequest 订单分账请求结构体
// 用于发起订单分账操作,支持向多个接收方进行分账
// 拉卡拉SDK接口文档订单分账接口
type OrderSplitLedgerRequest struct {
ReqData *OrderSplitLedgerReqData `json:"req_data"` // 请求业务数据
Version string `json:"version"` // 接口版本号
ReqTime string `json:"req_time"` // 请求时间格式为yyyyMMddHHmmss
}
// OrderSplitLedgerReqData 订单分账请求业务数据结构体
// 包含订单分账所需的详细业务参数
type OrderSplitLedgerReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号必传长度32
LogNo string `json:"log_no"` // 拉卡拉对账单流水号必传长度14posp流水号用于查询结算
LogDate string `json:"log_date"` // 交易日期必传长度8posp日期格式为yyyyMMdd用于查询结算
OutSeparateNo string `json:"out_separate_no"` // 商户分账指令流水号必传长度32每个商户号下唯一否则会校验失败
TotalAmt string `json:"total_amt"` // 分账总金额必传长度15单位为分
LklOrgNo string `json:"lkl_org_no"` // 拉卡拉机构编号条件必传长度16
CalType string `json:"cal_type"` // 分账计算类型条件必传长度2取值说明0-按照指定金额1-按照指定比例默认0
NotifyUrl string `json:"notify_url"` // 回调地址条件必传长度128分账、分账撤销或分账回退时通过该地址通知商户最终处理结果不传时不回调
RecvDatas []*OrderSplitLedgerRecvDatas `json:"recv_datas,omitempty"` // 分账接收数据对象,条件必传,列表类型,分账接收方编号必须已创建
}
type OrderSplitLedgerRecvDatas struct {
RecvMerchantNo string `json:"recv_merchant_no"` // 接收方商户号条件必传长度32分账接收方商户号分给自己时使用需和merchantNo一样否则检查报错分账接收方商户号和分账接收方只能填写一个
RecvNo string `json:"recv_no"` // 分账接收方编号条件必传长度32分账接收方编号分给他人时使用分账接收方商户号和分账接收方只能填写一个
SeparateValue string `json:"separate_value"` // 分账数值必传长度32calType为0时按照固定金额分账单位calType为1时按照比例分账单位百分比的小数值如0.55表示55%
}
// OrderSplitLedgerResponse 订单分账响应结构体
// 包含订单分账操作的处理结果信息
type OrderSplitLedgerResponse struct {
Msg string `json:"msg"` // 响应消息,描述响应结果
RespTime string `json:"resp_time"` // 响应时间格式为yyyyMMddHHmmss
Code string `json:"code"` // 响应码SACS0000表示成功
RespData struct {
SeparateNo string `json:"separate_no"` // 分账指令流水号必传长度32分账系统生成唯一流水
OutSeparateNo string `json:"out_separate_no"` // 商户订单号必传长度32请求报文中的商户外部订单号
Status string `json:"status"` // 分账状态条件必传长度16取值说明处理中-PROCESSING已受理-ACCEPTED成功-SUCCESS失败-FAIL
LogNo string `json:"log_no"` // 拉卡拉对账单流水号条件必传长度14请求透返
LogDate string `json:"log_date"` // 拉卡拉订单日期条件必传长度8posp日期格式为yyyyMMdd用于查询结算
TotalAmt string `json:"total_amt"` // 分账总金额条件必传长度15单位为分
} `json:"resp_data"` // 响应业务数据当code为SACS0000时返回
}
// SuccessOrFail 判断分账请求是否成功
// 返回true表示成功false表示失败
func (s *OrderSplitLedgerResponse) SuccessOrFail() bool {
return s.Code == "SACS0000"
}

76
model/preorder.go Normal file
View File

@ -0,0 +1,76 @@
package model
import "github.com/gogf/gf/v2/os/gtime"
// Preorder 预下单请求结构体
type Preorder struct {
ReqTime string `json:"req_time"` // 请求时间格式YYYYMMDDHHMMSS
Version string `json:"version"` // 接口版本号,固定值"3.0"
ReqData *PreorderReqData `json:"req_data"` // 请求业务数据
}
// PreorderReqData 预下单请求业务数据
type PreorderReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号拉卡拉分配的商户号String(32)
TermNo string `json:"term_no"` // 终端号拉卡拉分配的业务终端号String(32)
OutTradeNo string `json:"out_trade_no"` // 商户交易流水号商户系统唯一对应数据库表中外请求流水号String(32)
AccountType string `json:"account_type"` // 钱包类型微信WECHAT 支付宝ALIPAY 银联UQRCODEPAY 翼支付BESTPAY 苏宁易付宝SUNING 拉卡拉支付账户LKLACC 网联小钱包NUCSPAY 京东钱包JDString(32)
TransType string `json:"trans_type"` // 接入方式41:NATIVEALIPAY, 云闪付支持, 京东白条分期51:JSAPI微信公众号支付, 支付宝服务窗、JS支付, 翼支付JS支付, 拉卡拉钱包支付, 京东白条分期71:微信小程序支付61:APP支付微信APP支付String(2)
TotalAmount string `json:"total_amount"` // 金额单位分整数型字符String(12)
NotifyUrl string `json:"notify_url"` // 商户通知地址,商户通知地址,如果上传,且 pay_order_no 不存在情况下则按此地址通知商户String(128)
LocationInfo struct {
RequestIp string `json:"request_ip"` // 请求方IP地址存在必填格式如36.45.36.95String(64)
Location string `json:"location"` // 纬度,经度,商户终端的地理位置,银联二维码交易必填,整体格式:纬度,经度,+表示北纬、东经,-表示南纬、西经。经度格式1位正负号+3位整数+1位小数点+5位小数纬度格式1位正负号+2位整数+1位小数点+6位小数举例+31.221345,+121.12345String(32)
} `json:"location_info"` // 地址位置信息Object
Subject string `json:"subject"` // 订单标题用于简单描述订单或商品主题传输给账户端账户端控制实际最多42个字节微信支付必送String(42)
}
func NewPreorder(param *PreorderReqData) *Preorder {
return &Preorder{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "3.0",
ReqData: param,
}
}
// PreorderResponse 预下单响应结构体
type PreorderResponse struct {
Code string `json:"code"` // 响应码BBS00000表示成功
Msg string `json:"msg"` // 响应信息,对响应码的文字描述
ReqData ReqData `json:"resp_data"` // 响应业务数据
RespTime string `json:"resp_time"` // 响应时间
}
// ReqData 响应业务数据
type ReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号
OutTradeNo string `json:"out_trade_no"` // 外部订单号(商户订单号)
TradeNo string `json:"trade_no"` // 交易号,拉卡拉生成的订单号
LogNo string `json:"log_no"` // 拉卡拉对账单流水号
SettleMerchantNo string `json:"settle_merchant_no"` // 结算商户号
SettleTermNo string `json:"settle_term_no"` // 结算终端号
AccRespFields WxPreorderResponse `json:"acc_resp_fields"` // 支付通道返回的具体信息
}
// WxPreorderResponse 支付通道返回的具体信息
type WxPreorderResponse struct {
Code string `json:"code"` // 返回码
CodeImage string `json:"code_image"` // 二维码图片Base64编码
PrepayId string `json:"prepay_id"` // 预支付ID
AppId string `json:"app_id"` // 应用ID
PaySign string `json:"pay_sign"` // 签名
TimeStamp string `json:"time_stamp"` // 时间戳
NonceStr string `json:"nonce_str"` // 随机字符串
Package string `json:"package"` // 订单详情扩展字符串
SignType string `json:"sign_type"` // 签名方式
FormData string `json:"form_data"` // 表单数据
RedirectUrl string `json:"redirect_url"` // 重定向URL
BestPayInfo string `json:"best_pay_info"` // 翼支付信息
PartnerId string `json:"partner_id"` // 合作伙伴ID
SubMchId string `json:"sub_mch_id"` // 子商户ID
}
func (p *PreorderResponse) SuccessOrFail() bool {
return p.Code == "BBS00000"
}

90
model/queryLedgerMer.go Normal file
View File

@ -0,0 +1,90 @@
package model
// QueryLedgerMerRequest 分账商户查询请求结构体
// 用于向拉卡拉接口发送分账商户查询请求
// 包含请求头信息和业务数据
type QueryLedgerMerRequest struct {
// 请求业务数据
ReqData *QueryLedgerMerReqData `json:"req_data"`
// 接口版本号
Version string `json:"version"`
// 请求时间格式为yyyyMMddHHmmss
ReqTime string `json:"req_time"`
}
// QueryLedgerMerReqData 分账商户查询请求业务数据结构体
// 包含分账商户查询所需的具体业务参数
// 用于查询商户的分账设置信息
type QueryLedgerMerReqData struct {
// 接口版本号必传长度8取值说明1.0
Version string `json:"version"`
// 订单编号便于后续跟踪排查问题及核对报文必传长度32取值说明14位年月日24小时制分秒+8位的随机数不重复
OrderNo string `json:"order_no"`
// 机构代码必传长度32
OrgCode string `json:"org_code"`
// 拉卡拉内部商户号可选长度32取值说明拉卡拉内部商户号和银联商户号必须传一个都送以内部商户号为准
MerInnerNo string `json:"mer_inner_no"`
// 银联商户号可选长度32取值说明拉卡拉内部商户号和银联商户号必须传一个都送以内部商户号为准
MerCupNo string `json:"mer_cup_no"`
}
// QueryLedgerMerResponse 分账商户查询响应结构体
// 拉卡拉接口返回的分账商户查询响应数据
// 包含响应状态码、消息和业务数据
type QueryLedgerMerResponse struct {
// 响应状态码000000表示成功
Code string `json:"code"`
// 响应消息
Msg string `json:"msg"`
// 响应业务数据当code为000000时返回
RespData *QueryLedgerMerRespData `json:"resp_data"`
}
// QueryLedgerMerRespData 分账商户查询响应业务数据结构体
// 包含分账商户查询返回的具体业务信息
type QueryLedgerMerRespData struct {
// 分账商户机构号
OrgId string `json:"org_id"`
// 分账商户机构名称
OrgName string `json:"org_name"`
// 拉卡拉内部商户号
MerInnerNo string `json:"mer_inner_no"`
// 银联商户号
MerCupNo string `json:"mer_cup_no"`
// 最低分账比例百分比支持2位精度取值说明70或70.50
SplitLowestRatio string `json:"split_lowest_ratio"`
// 商户分账状态取值说明VALID启用INVALID禁用
SplitStatus string `json:"split_status"`
// 分账范围取值说明ALL全部交易分账(商户所有交易默认待分账)MARK标记交易分账(只有带分账标识交易待分账,其余交易正常结算)默认MARK
SplitRange string `json:"split_range"`
// 分账依据取值说明TR或空交易分账BA余额分账默认TR交易分账
SepFundSource string `json:"sep_fund_source"`
// 平台ID取值说明如果商户和绑定平台分账返回平台ID
PlatformId string `json:"platform_id"`
// 分账发起方式取值说明AUTO自动规则分账POINTRULE指定规则分账MANUAL手动规则分账
SplitLaunchMode string `json:"split_launch_mode"`
// 分账规则来源取值说明MER商户分账规则PLATFORM平台分账规则
SplitRuleSource string `json:"split_rule_source"`
// 已绑定接收方列表
BindRelations []BindRelation `json:"bind_relations"`
}
// BindRelation 已绑定接收方信息结构体
// 用于表示分账商户已绑定的接收方信息
type BindRelation struct {
// 拉卡拉内部商户号
MerInnerNo string `json:"mer_inner_no"`
// 银联商户号
MerCupNo string `json:"mer_cup_no"`
// 接收方编号
ReceiverNo string `json:"receiver_no"`
// 接收方编号名称
ReceiverName string `json:"receiver_name"`
}
// SuccessOrFail 判断分账商户查询请求是否成功
// 成功条件响应码为000000
// 返回值true表示成功false表示失败
func (resp *QueryLedgerMerResponse) SuccessOrFail() bool {
return resp.Code == "000000"
}

70
model/refund.go Normal file
View File

@ -0,0 +1,70 @@
package model
import "github.com/gogf/gf/v2/os/gtime"
// Refund 退款请求结构体
type Refund struct {
ReqTime string `json:"req_time"` // 请求时间格式YYYYMMDDHHMMSS
Version string `json:"version"` // 接口版本号,固定值"3.0"
ReqData *RefundReqData `json:"req_data"` // 请求业务数据
}
// RefundReqData 退款请求业务数据
type RefundReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号拉卡拉分配的商户号String(32),必填
TermNo string `json:"term_no"` // 终端号拉卡拉分配的业务终端号String(32),必填
OutTradeNo string `json:"out_trade_no"` // 商户请求流水号商户系统唯一String(32),必填
RefundAmount string `json:"refund_amount"` // 退款金额单位分整数型字符String(12),必填
RefundAccMode string `json:"refund_acc_mode"` // 退款账户模式String(2)必填00-调用户余额 65-调商户余额 66-调终端余额 30-调账户
LocationInfo struct {
RequestIp string `json:"request_ip"` // 请求方IP地址请求方的IP地址存在必填格式如36.45.36.95String(64),必填
} `json:"location_info"` // 地址位置信息Object必填
NotifyUrl string `json:"notify_url"` // 后台通知地址交易结果通知地址String(128),选填
OriginLogNo string `json:"origin_log_no"` // 拉卡拉对账单流水号正常退款的拉卡拉对账单流水号String(14),选填
OriginOutTradeNo string `json:"origin_out_trade_no"` // 原始交易商户流水号String(32),选填
OriginTradeNo string `json:"origin_trade_no"` // 原交易拉卡拉交易订单号String(32),选填
RefundSplitMsg string `json:"refund_split_msg"` // 退款分账状态String(2)选填00-为默认01-为分账;分账交易退款必须填写。需要退款上送该笔的分账状态,为分账时,是退分账前处理,还是退分账后处理
}
// NewRefund 创建退款请求
func NewRefund(param *RefundReqData) *Refund {
return &Refund{
ReqTime: gtime.Now().Format("YmdHis"),
Version: "3.0",
ReqData: param,
}
}
// RefundResponse 退款响应结构体
type RefundResponse struct {
Code string `json:"code"` // 响应码,"000000"表示成功
Msg string `json:"msg"` // 响应信息,对响应码的文字描述
RespData RefundRespData `json:"resp_data"` // 响应业务数据
RespTime string `json:"resp_time"` // 响应时间
}
// RefundRespData 退款响应业务数据
type RefundRespData struct {
TradeState string `json:"trade_state"` // 交易状态String(15)必填INIT-初始化需商户确认结果SUCCESS-交易成功FAIL-交易失败REFUND-交易退款中需商户确认结果PROCESSING-交易处理中需商户确认结果TIMEOUT-请求超时需商户确认结果EXCEPTION-异常(失败)
RefundType string `json:"refund_type"` // 退款模式String(20),必填
MerchantNo string `json:"merchant_no"` // 商户号拉卡拉分配的商户号String(32),必填
OutTradeNo string `json:"out_trade_no"` // 商户请求流水号请求报文中的商户请求流水号String(32),必填
TradeNo string `json:"trade_no"` // 拉卡拉交易流水号String(32),必填
LogNo string `json:"log_no"` // 拉卡拉对账单流水号String(14),必填
AccType string `json:"acc_type"` // 账户类型String(32),必填
TotalAmount string `json:"total_amount"` // 交易金额单位分整数型字符String(12),必填
RefundAmount string `json:"refund_amount"` // 申请退款金额单位分整数型字符String(12),必填
PayedAmount string `json:"payed_amount"` // 实际退款金额单位分整数型字符String(12),必填
TradeTime string `json:"trade_time"` // 退款时间实际退款时间格式yyyyMMddHHmmssString(14),选填
OriginLogNo string `json:"origin_log_no"` // 原拉卡拉对账单流水号原交易的拉卡拉对账单流水号String(14),选填
OriginOutTradeNo string `json:"origin_out_trade_no"` // 原商户请求流水号原交易中的商户请求流水号String(32),选填
OriginTradeNo string `json:"origin_trade_no"` // 原交易拉卡拉交易订单号String(32),选填
UpCouponInfo string `json:"up_coupon_info"` // 银联优惠券信息,目标字段,单位是银联侧返回的四部分内容:{"fundChannel": "BOC", "amount": "10"}String(500),选填
TanteInfo string `json:"tante_info"` // 淘方信息,目标字段,数据是淘方侧返回的四部分内容:{"fundChannel": "BOC", "amount": "10"}String(32),选填
ChannelRetDesc string `json:"channel_ret_desc"` // 渠道返回描述String必填codeMsg: "R000000-成功", "R011122-渠道处理超时"
}
// SuccessOrFail 判断退款交易是否成功
func (r *RefundResponse) SuccessOrFail() bool {
return r.Code == "000000"
}

43
model/separate.go Normal file
View File

@ -0,0 +1,43 @@
package model
type SeparateRequest struct {
ReqData *SeparateReqData `json:"req_data"` // 请求数据
Version string `json:"version"` // 版本号
ReqTime string `json:"req_time"` // 请求时间
}
type SeparateReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号
LogDate string `json:"log_date"` // 交易日期 yyyyMMdd查清结算用
LogNo string `json:"log_no"` // 拉卡拉对账单流水号
OutSeparateNo string `json:"out_separate_no"` // 商户分账指令流水号
TotalAmt string `json:"total_amt"` // 分账总金额 [单位:分]
LklOrgNo string `json:"lkl_org_no"` // 拉卡拉机构编号 非必填
CalType string `json:"cal_type"` // 分账计算类型 0- 按照指定金额1- 按照指定比例。默认 0 非必填
SeparateType string `json:"separate_type"`
NotifyUrl string `json:"notify_url"` // 回调地址 分账,分账撤销或分账回退时,是异步接口。通过该地址通知商户最终处理结果。不传时,不回调
RecvDatas []*SeparateRecvDatas `json:"recv_datas"` // 分账接收数据对象 分账接收方编号必须已创建
}
type SeparateRecvDatas struct {
RecvMerchantNo string `json:"recv_merchant_no,omitempty"` // 接收方商户号 分账接收方商户号分给自己时使用需和merchantNo一样否则检查报错分账接收方商户号 和 分账接收方 只能填写一个。
SeparateValue string `json:"separate_value"` // 分账数值 calType为0时按照固定金额分账单位分 calType为1时按照比例分账单位百分比的小数值比如0.55 55%
RecvNo string `json:"recv_no,omitempty"` // 分账接收方编号 分账接收方编号, 分给他人时使用;分账接收方商户号 和 分账接收方 只能填写一个。
}
type SeparateResponse struct {
Msg string `json:"msg"`
RespTime string `json:"resp_time"`
Code string `json:"code"`
RespData struct {
TotalAmt string `json:"total_amt"` // 分账总金额 单位:分
LogDate string `json:"log_date"` // 拉卡拉订单日期 posp日期yyyyMMdd查清结算用
SeparateNo string `json:"separate_no"` // 分账指令流水号 分账系统生成唯一流水
LogNo string `json:"log_no"` // 拉卡拉对账单流水号 请求透返
OutSeparateNo string `json:"out_separate_no"` // 商户订单号 请求报文中的商户外部订单号
Status string `json:"status"` // 分账状态 处理中PROCESSING, 已受理ACCEPTED, 成功SUCCESS, 失败FAIL
} `json:"resp_data"`
}
func (s *SeparateResponse) SuccessOrFail() bool {
return s.Code == "SACS0000"
}

View File

@ -0,0 +1,39 @@
package model
// SplitBalanceRequest 可分账金额查询请求结构体
// 用于查询指定交易的可分账金额信息
// 拉卡拉SDK接口文档可分账金额查询接口
type SplitBalanceRequest struct {
ReqData *SplitBalanceReqData `json:"req_data"` // 请求业务数据
Version string `json:"version"` // 接口版本号
ReqTime string `json:"req_time"` // 请求时间格式为yyyyMMddHHmmss
}
// SplitBalanceReqData 可分账金额查询请求业务数据结构体
// 包含可分账金额查询所需的查询参数
type SplitBalanceReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号必传长度32
LogDate string `json:"log_date"` // 拉卡拉对账单交易日期必传长度8格式为yyyyMMdd用于查询结算
LogNo string `json:"log_no"` // 拉卡拉对账单流水号必传长度14对应pos流水号用于查询结算
}
// SplitBalanceResponse 可分账金额查询响应结构体
// 包含可分账金额查询的结果信息
type SplitBalanceResponse struct {
Msg string `json:"msg"` // 响应消息,描述响应结果
RespTime string `json:"resp_time"` // 响应时间格式为yyyyMMddHHmmss
Code string `json:"code"` // 响应码SACS0000表示成功
RespData struct {
MerchantNo string `json:"merchant_no"` // 商户号,请求返回
TotalSeparateAmt string `json:"total_separate_amt"` // 总分账金额必传长度15单位为分
CanSeparateAmt string `json:"can_separate_amt"` // 可分账金额必传长度15单位为分
LogDate string `json:"log_date"` // 拉卡拉对账单交易日期必传长度8格式为yyyyMMdd
LogNo string `json:"log_no"` // 拉卡拉对账单流水号必传长度14请求返回
} `json:"resp_data"` // 响应业务数据当code为SACS0000时返回
}
func (s *SplitBalanceResponse) SuccessOrFail() bool {
return s.Code == "SACS0000"
}

73
model/tradeQuery.go Normal file
View File

@ -0,0 +1,73 @@
package model
// TradeQuery 交易查询请求结构体
type TradeQuery struct {
ReqTime string `json:"req_time"` // 请求时间
Version string `json:"version"` // API版本号
OutOrgCode string `json:"out_org_code"` // 外部机构码
ReqData *TradeQueryReqData `json:"req_data"` // 请求数据
}
// TradeQueryReqData 交易查询请求数据结构体
type TradeQueryReqData struct {
MerchantNo string `json:"merchant_no"` // 商户号,必传
TermNo string `json:"term_no"` // 终端号,必传
OutTradeNo string `json:"out_trade_no"` // 商户交易流水号条件必传与trade_no必传其一
}
// TradeQueryResponse 交易查询响应结构体
type TradeQueryResponse struct {
Msg string `json:"msg"` // 响应消息
RespTime string `json:"resp_time"` // 响应时间
Code string `json:"code"` // 响应码000000表示成功
RespData struct {
MerchantNo string `json:"merchant_no"` // 商户号,必传
OutTradeNo string `json:"out_trade_no"` // 商户请求流水号,必传
TradeNo string `json:"trade_no"` // 拉卡拉商户订单号,必传
LogNo string `json:"log_no"` // 拉卡拉对账流水号,必传
TradeMainType string `json:"trade_main_type"` // 交易大类条件必传PREORDER-主扫MICROPAY-被扫REFUND-退款CANCEL-撤销)
SplitAttr string `json:"split_attr"` // 拆单属性条件必传M-主单S-子单)
SplitInfo []struct {
SubTradeNo string `json:"sub_trade_no"` // 子单交易流水号,必传
SubLogNo string `json:"sub_log_no"` // 子单对账单单流水号,必传
OutSubTradeNo string `json:"out_sub_trade_no"` // 外部子交易流水号,必传
MerchantNo string `json:"merchant_no"` // 商户号,必传
MerchantName string `json:"merchant_name"` // 商户名称,必传
TermNo string `json:"term_no"` // 终端号,必传
Amount string `json:"amount"` // 金额,必传(单位分)
} `json:"split_info"` // 拆单信息,条件必传(如果查询订单是主单,则返回)
RefundSplitInfo []struct {
OutSubTradeNo string `json:"out_sub_trade_no"` // 外部子退款交易流水号,必传
MerchantNo string `json:"merchant_no"` // 商户号,必传
TermNo string `json:"term_no"` // 终端号,必传
RefundAmount string `json:"refund_amount"` // 申请退款金额,必传(单位分)
SubTradeNo string `json:"sub_trade_no"` // 拉卡分子交易流水号,条件必传
SubLogNo string `json:"sub_log_no"` // 对账单子流水号,条件必传
TradeState string `json:"trade_state"` // 子交易状态条件必传SUCCESS-交易成功 FAIL-交易失败)
ResultCode string `json:"result_code"` // 处理结果码,条件必传
ResultMsg string `json:"result_msg"` // 处理描述,条件必传
} `json:"refund_split_info"` // 合单退款拆单信息,条件必传(如果查询订单是退款主单,则返回)
AccTradeNo string `json:"acc_trade_no"` // 账户端交易订单号,必传
AccountType string `json:"account_type"` // 钱包类型,必传(微信: WECHAT 支付宝: ALIPAY 银联: UQRCODEPAY 翼支付: BESTPAY 苏宁支付: SUNING
TradeState string `json:"trade_state"` // 交易状态必传INIT-初始化 CREATE-下单成功 SUCCESS-交易成功 FAIL-交易失败 DEAL-交易处理中 UNKNOWN-未知状态 CLOSE-订单关闭 PART_REFUND-部分退款 REFUND-全部退款)
TradeStateDesc string `json:"trade_state_desc"` // 交易状态描述,条件必传
TotalAmount string `json:"total_amount"` // 订单金额,必传(单位分)
PayerAmount string `json:"payer_amount"` // 付款人实付金额,条件必传(单位分)
AccSettleAmount string `json:"acc_settle_amount"` // 账户端结算金额,条件必传(单位分)
AccMdiscountAmount string `json:"acc_mdiscount_amount"` // 商户侧优惠金额,条件必传(单位分)
AccDiscountAmount string `json:"acc_discount_amount"` // 账户端优惠金额,条件必传(单位分)
AccOtherDiscountAmount string `json:"acc_other_discount_amount"` // 账户端其它优惠金额,条件必传(单位分)
TradeTime string `json:"trade_time"` // 交易完成时间条件必传yyyyMMddHHmmss
UserId1 string `json:"user_id1"` // 用户标识1条件必传微信sub_open_id 支付宝buyer_login_id 买家支付账号)
UserId2 string `json:"user_id2"` // 用户标识2条件必传微信open_id 支付宝buyer_user_id 银user_id
BankType string `json:"bank_type"` // 付款银行,条件必传
CardType string `json:"card_type"` // 银行卡类型条件必传00: 借记卡 01: 贷记卡 02: 微信零钱 03: 支付宝花呗 04: 支付宝其他 05: 数字货币 06: 拉卡拉支付账户 99: 未知)
AccActivityId string `json:"acc_activity_id"` // 活动ID条件必传在账户端商户后台配置的批次ID
TradeReqDate string `json:"trade_req_date"` // 交易请求日期必传yyyyMMdd
AccRespFields map[string]interface{} `json:"acc_resp_fields"` // 账户端返回信息域,条件必传
} `json:"resp_data"` // 响应数据
}
func (t *TradeQueryResponse) SuccessOrFail() bool {
return t.Code == "000000"
}

36
model/uploadFile.go Normal file
View File

@ -0,0 +1,36 @@
package model
type UploadFileRequest struct {
ReqData *UploadFileReqData `json:"reqData"`
Ver string `json:"ver"`
Timestamp string `json:"timestamp"`
ReqId string `json:"reqId"`
}
type UploadFileReqData struct {
Version string `json:"version"`
OrderNo string `json:"orderNo"`
AttType string `json:"attType"`
AttExtName string `json:"attExtName"`
AttContext string `json:"attContext"`
OrgCode string `json:"orgCode"`
}
type UploadFileResponse struct {
CmdRetCode string `json:"cmdRetCode"`
ReqId string `json:"reqId"`
RespData struct {
AttType string `json:"attType"`
OrderNo string `json:"orderNo"`
OrgCode string `json:"orgCode"`
AttFileId string `json:"attFileId"`
} `json:"respData"`
RetCode string `json:"retCode"`
RetMsg string `json:"retMsg"`
Timestamp int64 `json:"timestamp"`
Ver string `json:"ver"`
}
func (u *UploadFileResponse) SuccessOrFail() bool {
return u.RetCode == "000000"
}

67
model/withdraw.go Normal file
View File

@ -0,0 +1,67 @@
package model
// WithdrawRequest 提现请求结构体
// 用于向拉卡拉接口发送提现请求
// 包含请求头信息和业务数据
type WithdrawRequest struct {
// 请求业务数据
ReqData *WithdrawReqData `json:"req_data"`
// 接口版本号
Version string `json:"version"`
// 请求时间格式为yyyyMMddHHmmss
ReqTime string `json:"req_time"`
}
// WithdrawReqData 提现请求业务数据结构体
// 包含提现所需的具体业务参数
// 用于申请账户资金提现
type WithdrawReqData struct {
// bmcp机构号必传最大长度32
OrgNo string `json:"org_no"`
// 商户号必传最大长度32822商户号SR分账接收方编号
MerchantNo string `json:"merchant_no"`
// 提现金额单位必传最大长度32
DrawAmt string `json:"draw_amt"`
// 通知地址非必传最大长度256
NotifyUrl string `json:"notify_url"`
// 商户订单号商户系统唯一非必传最大长度256
MerOrderNo string `json:"mer_order_no"`
// 账号若该参数上送则payType将无效非必传最大长度32
PayNo string `json:"pay_no"`
// 账号类型01收款账户04分账接收方账户未上送则默认01必传最大长度32分账接收方提现时需填04
PayType string `json:"pay_type"`
// 备注信息非必传最大长度64
Remark string `json:"remark"`
// 摘要非必传最大长度64
Summary string `json:"summary"`
// 结算银行ID非必传最大长度32
BankId string `json:"bank_id"`
}
// WithdrawResponse 提现响应结构体
// 拉卡拉接口返回的提现响应数据
// 包含响应状态码、消息和业务数据
type WithdrawResponse struct {
// 响应状态码000000表示成功
Code string `json:"code"`
// 响应消息
Msg string `json:"msg"`
// 响应业务数据当code为000000时返回
RespData *WithdrawRespData `json:"resp_data"`
}
// WithdrawRespData 提现响应业务数据结构体
// 包含提现返回的具体业务信息
type WithdrawRespData struct {
// 提现流水号,必传
DrawJnl string `json:"draw_jnl"`
// 商户订单号,必传
MerOrderNo string `json:"mer_order_no"`
}
// SuccessOrFail 判断提现请求是否成功
// 成功条件响应码为000000
// 返回值true表示成功false表示失败
func (resp *WithdrawResponse) SuccessOrFail() bool {
return resp.Code == "000000"
}