first commit

This commit is contained in:
maguodong
2025-10-09 15:56:47 +08:00
commit ccd273840a
32 changed files with 2020 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+6
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
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
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>
Generated
+6
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
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
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
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
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
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
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
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
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
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
}
+77
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
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
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
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
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"
}
+104
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
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
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
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 京东钱包:JD,String(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.95,String(64),必填
BaseStation string `json:"base_station"` // 基站信息,客户端设备的基站信息(主扫时基站信息使用该字段),String(128),选填
Location string `json:"location"` // 维度,经度,商户终端的地理位置,存在必填格式:纬度,经度,+表示北纬、东经,-表示南纬、西经,精度最长支持小数点后9位。举例:+37.123456789,121.123456789,String(32),选填
}
// AccBusiFields 账户端业务信息域,微信主扫场景
type AccBusiFields struct {
TimeoutExpress string `json:"timeout_express"` // 预下单的订单的有效时间,以分钟为单位。如果在有效时间内没有完成付款,则在账户端该订单失效。如用户超时,则账户端完成失效处理,建议不超过15分钟。不传值则默认5分钟,String(2),选填
SubAppId string `json:"sub_appid"` // 子商户公众账号ID,sub_appid(即微信小程序支付-71、公众号支付-51、微信支付-61),此参数必传,只对微信支付生效;拉卡拉钱包情况下,该字段上送LAKALA的openid,String(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
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"` // 拉卡拉对账单流水号,必传,长度14,posp流水号,用于查询结算
LogDate string `json:"log_date"` // 交易日期,必传,长度8,posp日期,格式为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"` // 分账数值,必传,长度32,calType为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"` // 拉卡拉订单日期,条件必传,长度8,posp日期,格式为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
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 京东钱包:JD,String(32)
TransType string `json:"trans_type"` // 接入方式,41:NATIVE(ALIPAY, 云闪付支持, 京东白条分期)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.95,String(64)
Location string `json:"location"` // 纬度,经度,商户终端的地理位置,银联二维码交易必填,整体格式:纬度,经度,+表示北纬、东经,-表示南纬、西经。经度格式:1位正负号+3位整数+1位小数点+5位小数;纬度格式:1位正负号+2位整数+1位小数点+6位小数;举例:+31.221345,+121.12345,String(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
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
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.95,String(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"` // 退款时间,实际退款时间,格式:yyyyMMddHHmmss,String(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
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"
}
+39
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
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
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
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"`
// 商户号,必传,最大长度32,822商户号,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"
}