commit
ccd273840a
|
|
@ -0,0 +1,8 @@
|
|||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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. 如遇到问题,请参考拉卡拉官方文档或联系技术支持
|
||||
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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
|
||||
)
|
||||
|
|
@ -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=
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"`
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
|
|
@ -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"
|
||||
}
|
||||
Loading…
Reference in New Issue