第三章 接口参数 - 资金管理
## 3 资金管理
## 3.1 充值接口
开发环境:https://pay-dev.lx-rhino.com
生产环境:https://api.lx-rhino.com
#### 接口地址:
/open/api/v1/balance/recharge
#### 请求方式:POST
#### 请求参数说明:
|参数名称|参数含义|是否必填|参数备注|
|-|-|-|-|
|mainstayId|主体ID|是||
|payType|支付类型|否|0:银行卡账户 1:支付宝账户。默认为0(银行卡账户充值)|
|amount|充值金额|是||
|bankVoucherFile|充值银行回执单|否|该参数为通过[4.上传文件接口](https://easydoc.xyz/doc/67068226/iYZ0vo48/Y92UlsjW)将文件上传后返回的值|
|remarks|备注|否||
|thirdRechargeNo|第三方充值单号|是||
#### 接口响应参数data字段解密后的参数说明:
|参数名称| 参数含义|数据类型| 是否必有| 参数备注|
|-|-|-|-|-|
|thirdRechargeNo| 第三方充值单号| String|是||
|entryAmount| 打款金额|String|是||
|rechargeAmount| 实际充值到账金额(扣除税费)|String|是| ||
|contractTaxRate| 税率|String|是| ||
|contractTaxAmount| 税费|String|是| ||
## 3.2 提现接口
**解释说明:**
>d 支持在线提现接口
**环境选择:**
开发环境:https://pay-dev.lx-rhino.com
生产环境:https://api.lx-rhino.com
**接口地址:**
/open/api/v1/balance/withdraw
**请求参数说明:**
|参数名称 |参数含义 |是否必填 |参数备注|
|-|-|-|-|
|mainstayId |主体ID |是||
|transAmount |交易金额 |是||
|transNo |交易单号 |否| 该参数为蓝犀的关联订单号 例如:提交发放的订单号返回billId=1则填写1即可。有则填写|
|thirdTransNo |第三方交易单号 |是 |该值具有唯一性|
**接口响应参数data字段解密后的参数说明:**
|参数名称 |参数含义 |是否必有 |参数备注|
|-|-|-|-|
|rechargeAmount |充值金额 |是 |该值代表实际在发放平台扣除的金额(反算税率所得)|
|thirdTransNo |第三方交易订单号| 是||
## 3.3 退款结果异步回调
**解释说明:**
>d 该接口需要第三方自行编写提供接口到发放平台回调成功必须返回success不然会重复回调
解密结果
示例如下:
```Java
{"refundTransNo":"","status":"","refundAmount":""}
```
|参数名称 |参数含义 |是否必有 |参数备注|
|-|-|-|-|
|refundTransNo |退款单号 |是 |如果是发放退款则该单号即为发放订单的thirdOrderNo|
|status |退款状态 |是 |详情请看退款状态码|
|refundAmount |退款金额 |是 |实际退款的金额|
#### 接口示例:
>d 该接口需要第三方自行编写提供接口到发放平台 接口编写示例如下。
#### 请求方式:POST
```java
@PostMapping("signCallBack")
@ResponseBody
public String signCallBack(HttpServletRequest request, @RequestBody String data){
String publicKey = "该公钥由发放平台提供发放到贵司邮箱";
//解密
String decode = RSAHelper.decryptByPublicKey(data, publicKey);
/*贵公司处理业务逻辑*/
return "success";
}
```
解密工具类在 [JAVA_DEMO](https://gitee.com/xinfudblog/lxapi_java_demo) 的 RSAHelper 类中
>d
> 1.贵司写完后提供到接口url给发放平台即可。回调成功必须返回success,不然会重复回调,至多重试8次。
> 2.每次回调的间隔时间2N次方分钟,比如第一次回调间隔时间为2分钟,第二次就为4分钟,依次往后推,最多重试8次;
postman中模拟接口是否正常接收数据如下操作

## 3.4 打款回调接口
**解释说明:**
>d 第三方支付平台走自己的打款渠道成功后回调同步订单状态
**环境选择:**
开发环境:https://pay-dev.lx-rhino.com
生产环境:https://api.lx-rhino.com
**接口地址:**
/open/api/v1/bill/payCallBack
**请求参数说明:**
|参数名称 |参数含义 |是否必填 |参数备注|
|-|-|-|-|
|thirdOrderId |第三方订单 |是 |生成订单的时候提交过来的订单号|
|status |打款状态 |是 |详情请参考[打款状态码](https://easydoc.xyz/doc/67068226/iYZ0vo48/KsTw3e7C)|
|message |打款返回信息| 否 |字数不可超过120个字符|
**接口响应参数data字段解密后的参数说明:**
该接口无需解密返回如下json字符串。如果 success等于true代表调用接口成功,如果success等于false则代表调用失败
结果示例:
```Java
{“resopnseType”:0,“errorCode”:"",“errorMessage”:"",“status”:0,“data”:null,“ext”:null,“extMessage”:null,“success”:true}
```
## 3.5 入金成功异步回调
>d 该接口需要第三方自行编写提供接口到发放平台回调成功必须返回success不然会重复回调 接口编写示例跟 3.3 退款结果异步回调说明一致
#### 请求方式:POST
解密结果示例如下:
```json
{"thirdRechargeNo":"xxxxx","rechargeAmount":"12.01","entryAmount":"10.01"}";
```
|参数名称| 参数含义| 是否必有| 参数备注|
|-|-|-|-|
|thirdRechargeNo| 充值订单号| 是|改充值订单号由双方约定规则前缀,否则不进行回调|
|rechargeAmount| 商户实际充值的金额| 是|商户实际充值了多少钱|
|entryAmount| 入金金额| 是|蓝犀平台入金金额|
## 4.上传文件接口(公共接口)
>d 该接口将需要上传的文件上传至发放平台服务器,获取到对应的地址用于其他接口作为入参
开发环境:https://pay-dev.lx-rhino.com
生产环境:https://api.lx-rhino.com
#### 接口地址:
/open/api/v1/invoices/uploadFile
#### 请求方式:POST
#### 请求参数说明:
|参数名称|参数含义|是否必填|参数备注|
|-|-|-|-|
|file|文件|是||
#### 响应参数说明:
|参数名称| 参数含义| 是否必有| 参数备注|
|-|-|-|-|
|url|文件地址|是||
java接口代码示例:
```json
@PostMapping(value = "/upload")
@ResponseBody
@NoPermission
public String upload(MultipartFile file) {
String url = baseUrl +"/open/api/v1/invoices/uploadFile";
final byte[] bytes ;
try {
bytes = file.getBytes();
String appKey = "";
String version = "1.0";
String secretkey = "";
String timestamp = String.valueOf(System.currentTimeMillis());
//注意此处签名无 body拼接
String localString = "&Timestamp=" + timestamp + "&AppKey=" + appKey + "&Version=" + version + "&SecretKey" + secretkey;
String sigin = Md5Util.getMd5(localString);
MultipartBody body = new MultipartBody.Builder()
.setType(MediaType.parse("multipart/form-data"))
.addFormDataPart("file", file.getOriginalFilename(), okhttp3.RequestBody.create(MediaType.parse("image/" + "打款凭证"), bytes))
.build();
Request request = new Request.Builder()
.post(body)
.addHeader("AppKey", appKey)
.addHeader("Timestamp", timestamp)
.addHeader("Version", "1.0")
.addHeader("Sign", sigin)
.url(url)
.build();
Call call = HttpUtil.getOkHttpClient().newCall(request);
try {
Response response = call.execute();
String res = response.body().string();
log.info("res====" + res);
return res;
} catch (IOException e) {
log.error("HttpUtil.post网络请求失败:{}", e.getMessage());
return "网络请求失败";
}
} catch (IOException e) {
log.warn("fail to read file", file.getOriginalFilename(), e);
}
return null;
}
```
postman 直接请求示例:
