概述
银行代付,是指商家可以在EPAY提现规定的当地币种到用户的银行账号。
支付流程
商家可以参考如下流程图,完成代付对接。
流程说明
- 用户访问您的页面发起快捷代付(提现)交易申请(银行或现金)。
- 您的后台服务调用getLimit接口到EPAY网关后台服务获取交易限额。
- EPAY网关后台服务响应获取交易限额。
- 您的后台服务调用交易前的接口查询各种交易信息和条件。
- EPAY网关后台服务响应查询的数据。
- 用户访问您的页面发起交易请求。
- 您的后台服务调用createTransaction接口到EPAY网关后台服务创建交易。
- EPAY网关后台服务创建临时订单:订单状态status=9。
- 如果订单时间大于10分钟,EPAY网关后台服务【主动】关闭订单:订单状态status=5,回调订单状态,并结束订单流程。
- 用户取消继续付款,您的后台服务调用cancelTransaction接口到EPAY网关后台服务取消订单。
- EPAY网关后台服务【主动】关闭订单,订单状态status=5,回调订单状态,并结束订单流程
- 您的后台服务调用confirmTransaction接口到EPAY网关后台服务确认交易。
- EPAY网关后台服务创建正式订单,开始处理:订单状态status=1
- EPAY网关后台服务调用第三方银行完成付款交易
- 第三方银行AcquireerBank回调结果发送到EPAY网关后台服务。
- EPAY网关后台服务处理订单结果,包括订单成功:订单状态status=7,订单失败:订单状态status=6,【现金支付】进入待取款:订单状态status=19。
- EPAY网关后台服务发送回调结果给您的后台服务,通知交易订单已完成。
- 您的后台服务可以选择调用queryTransaction接口进行信息确认。
- EPAY网关后台服务响应queryTransaction接口数据(对于现金业务,通过此接口查询取款码)。
- 您的后台服务更新交易数据,完成订单状态。
- 您的后台服务通知用户订单完成状态。
CNY添加银行账户
在发起交易前,需要先提交银行信息给银行渠道进行校验审核,审核通过后,就可以进行下单交易。
1.具体银行信息说明如下:
付款人资料:可固定传您的认证资料(指实际受益人),国籍、实际居住地址必须是中国以外的地区。
收款人资料:手机号码(中国)、证件号码(身份证)、银行账户。收款人必须是中国大陆公民。
2.商家对接银行信息事项说明如下:
首先调用 queryBankAccount接口 查询是否已添加过收款人银行信息,如未添加收款人银行信息,则调用 addBankAccount接口 添加收款人银行信息。如果已经添加完成收款人银行信息,则可以进行下一步的交易操作。
特别说明:如果用户开户未处理完成,发起交易操作,同时超过订单有效时间,未收到开户完成通知,订单将会超时关闭,资金原路返还。
建议发起交易前,确定用户开户已处理完成。
创建订单
商家后台请求 createTransaction 的API接口,传入商家订单号、订单金额、币种等参数,及其他必填字段(具体可查看如下入参说明),创建EPAY临时代付订单。
注意:此时订单状态为冻结中(status=9)。
在10分钟内,商家可以调用取消订单 cancelTransaction 的API接口,关闭订单状态(status=5),也可以调用确认交易 confirmTransaction API接口,创建正式订单(status=1)。
如果超过10分钟未完成交易操作,系统将关闭订单状态(status=5)。
示例代码
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"sign\": \"\",\n \"param\": {\n \"epayAccount\": \"test2020@epay.com\",\n \"category\": \"BANK\",\n \"notifyUrl\": \"\",\n \"merchantOrderNo\": \"202201019002\",\n \"amount\": \"100\",\n \"receiveAmount\": \"\",\n \"settlementCurrency\": \"USD\",\n \"receiveCurrency\": \"CNY\",\n \"version\": \"V2.0.0\",\n \"transactionType\": \"C2C\",\n \"senderInfo\": {\n \"surName\": \"Joe\",\n \"givName\": \"Chang\",\n \"idNumber\": \"A199267867\",\n \"idType\": \"1\",\n \"birthday\": \"1986-09-11\",\n \"country\": \"TW\",\n \"nationality\": \"TW\",\n \"address\": \"shenzhen\",\n \"purposeOfRemittance\":\"20\" \n },\n \"receiverInfo\": {\n \"surName\": \"lu\",\n \"givName\": \"hui\",\n \"country\": \"CN\",\n \"phone\":\"153666100\",\n \"locationId\": \"3460\",\n \"bankName\": \"AliPay\",\n \"email\":\"\",\n \"area\": \"236\"\n \n }\n }\n}");
Request request = new Request.Builder()
.url("http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/createTransaction")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"sign\": \"\",\n \"param\": {\n \"epayAccount\": \"test2020@epay.com\",\n \"category\": \"BANK\",\n \"notifyUrl\": \"\",\n \"merchantOrderNo\": \"202201019002\",\n \"amount\": \"100\",\n \"receiveAmount\": \"\",\n \"settlementCurrency\": \"USD\",\n \"receiveCurrency\": \"CNY\",\n \"version\": \"V2.0.0\",\n \"transactionType\": \"C2C\",\n \"senderInfo\": {\n \"surName\": \"Joe\",\n \"givName\": \"Chang\",\n \"idNumber\": \"A199267867\",\n \"idType\": \"1\",\n \"birthday\": \"1986-09-11\",\n \"country\": \"TW\",\n \"nationality\": \"TW\",\n \"address\": \"shenzhen\",\n \"purposeOfRemittance\":\"20\" \n },\n \"receiverInfo\": {\n \"surName\": \"lu\",\n \"givName\": \"hui\",\n \"country\": \"CN\",\n \"phone\":\"153666100\",\n \"locationId\": \"3460\",\n \"bankName\": \"AliPay\",\n \"email\":\"\",\n \"area\": \"236\"\n \n }\n }\n}");
Request request = new Request.Builder()
.url("http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/createTransaction")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
python
import requests
import json
url = "http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/createTransaction"
payload = json.dumps({
"sign": "",
"param": {
"epayAccount": "test2020@epay.com",
"category": "BANK",
"notifyUrl": "",
"merchantOrderNo": "202201019002",
"amount": "100",
"receiveAmount": "",
"settlementCurrency": "USD",
"receiveCurrency": "CNY",
"version": "V2.0.0",
"transactionType": "C2C",
"senderInfo": {
"surName": "Joe",
"givName": "Chang",
"idNumber": "A199267867",
"idType": "1",
"birthday": "1986-09-11",
"country": "TW",
"nationality": "TW",
"address": "shenzhen",
"purposeOfRemittance": "20"
},
"receiverInfo": {
"surName": "lu",
"givName": "hui",
"country": "CN",
"phone": "153666100",
"locationId": "3460",
"bankName": "AliPay",
"email": "",
"area": "236"
}
}
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/createTransaction"
method := "POST"
payload := strings.NewReader(`{
"sign": "",
"param": {
"epayAccount": "test2020@epay.com",
"category": "BANK",
"notifyUrl": "",
"merchantOrderNo": "202201019002",
"amount": "100",
"receiveAmount": "",
"settlementCurrency": "USD",
"receiveCurrency": "CNY",
"version": "V2.0.0",
"transactionType": "C2C",
"senderInfo": {
"surName": "Joe",
"givName": "Chang",
"idNumber": "A199267867",
"idType": "1",
"birthday": "1986-09-11",
"country": "TW",
"nationality": "TW",
"address": "shenzhen",
"purposeOfRemittance":"20"
},
"receiverInfo": {
"surName": "lu",
"givName": "hui",
"country": "CN",
"phone":"153666100",
"locationId": "3460",
"bankName": "AliPay",
"email":"",
"area": "236"
}
}
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
shell
printf '{
"sign": "",
"param": {
"epayAccount": "test2020@epay.com",
"category": "BANK",
"notifyUrl": "",
"merchantOrderNo": "202201019002",
"amount": "100",
"receiveAmount": "",
"settlementCurrency": "USD",
"receiveCurrency": "CNY",
"version": "V2.0.0",
"transactionType": "C2C",
"senderInfo": {
"surName": "Joe",
"givName": "Chang",
"idNumber": "A199267867",
"idType": "1",
"birthday": "1986-09-11",
"country": "TW",
"nationality": "TW",
"address": "shenzhen",
"purposeOfRemittance":"20"
},
"receiverInfo": {
"surName": "lu",
"givName": "hui",
"country": "CN",
"phone":"153666100",
"locationId": "3460",
"bankName": "AliPay",
"email":"",
"area": "236"
}
}
}'| http --follow --timeout 3600 POST 'http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/createTransaction' \
Content-Type:'application/json'
入参说明
参数名称 | 参数说明 |
---|---|
epayAccount | 商家开通的EPAY账号 |
merchantOrderNo | 商家订单号 |
version | 版本号,当前版本号为V2.0.0,兼容版本V1.0.0 |
category | 汇款方式:银行BANK,现金CASH |
notifyUrl | 回调地址,用于接收EPAY后台通知的订单结果:成功或失败 |
amount | 订单金额 |
settlementCurrency | 结算币种,多数情况传入USD |
receiveAmount | 收款金额 |
receiveCurrency | 收款币种,如CNY |
transactionType | 交易模式 (C2C,B2C,B2B,C2B) |
extendFields | 额外字段 |
senderInfo | 付款人信息,JSON格式,具体入参字段,根据 查询接口 获取后填写 注意:transactionType为C2C,C2B时必填 |
receiverInfo | 收款人信息,JSON格式,具体入参字段,根据 查询接口 获取后填写 注意:transactionType为C2C,B2C时必填 |
senderBusiness | 付款公司信息,JSON格式,具体入参字段,根据 查询接口 获取后填写 注意:transactionType为B2C,B2B时必填 |
receiverBusiness | 收款公司信息,JSON格式,具体入参字段,根据 查询接口 获取后填写 注意:transactionType为C2B,B2B时必填 |
以上为业务参数说明,参数封装结构及sign签名请查看 开发指引>接入指南>接口规则>接口规范 和 开发指引>接口签名 。
查询交易
商家可调用 queryTransaction(交易查询接口),通过商家订单号查询对应订单支付情况。
示例代码
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"param\": {\n \"epayAccount\": \"test2020@epay.com\",\n \"version\": \"V2.0.0\",\n \"merchantOrderNo\": \"20210708220\"\n },\n \"sign\": \"\"\n}");
Request request = new Request.Builder()
.url("http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/queryTransaction")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
java
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"param\": {\n \"epayAccount\": \"test2020@epay.com\",\n \"version\": \"V2.0.0\",\n \"merchantOrderNo\": \"20210708220\"\n },\n \"sign\": \"\"\n}");
Request request = new Request.Builder()
.url("http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/queryTransaction")
.method("POST", body)
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
python
import requests
import json
url = "http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/queryTransaction"
payload = json.dumps({
"param": {
"epayAccount": "test2020@epay.com",
"version": "V2.0.0",
"merchantOrderNo": "20210708220"
},
"sign": ""
})
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
go
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/queryTransaction"
method := "POST"
payload := strings.NewReader(`{
"param": {
"epayAccount": "test2020@epay.com",
"version": "V2.0.0",
"merchantOrderNo": "20210708220"
},
"sign": ""
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
shell
printf '{
"param": {
"epayAccount": "test2020@epay.com",
"version": "V2.0.0",
"merchantOrderNo": "20210708220"
},
"sign": ""
}'| http --follow --timeout 3600 POST 'http://29597375fx.epaydev.xyz/capi/openapi/payoutApi/queryTransaction' \
Content-Type:'application/json'
入参说明
参数名称 | 参数说明 |
---|---|
epayAccount | 商家开通的EPAY账号 |
merchantOrderNo | 商家订单号 |
version | 版本号,当前版本号为V2.0.0,兼容版本V1.0.0 |
以上为业务参数说明,参数封装结构及sign签名请查看 开发指引>接入指南>接口规则>接口规范 和 开发指引>接口签名 。
异步通知
EPAY通过POST 请求的方式(也可以通过创建订单时传入的successUrlMethod或者failUrlMethod字段来设置回调的请求方式)将支付结果作为参数通知到notifyUrl(创建订单时设置的地址),商家收到异步通知后可以对sign签名值做安全性校验,判断消息来源是EPAY后再对自身业务做逻辑处理。具体sign签名方法请查看 开发指引>接口签名。
异步通知示例,请查看 开发指引>异步通知>回调示例
订单状态图
API列表
API名称 | API描述 | 操作 |
---|---|---|
queryBankAccount | 查询银行账户 | 查看文档 |
addBankAccount | 添加银行账户 | 查看文档 |
getRequiredField | 获取必填字段 | 查看文档 |
getBankList | 获取银行网点 | 查看文档 |
getCatalogue | 获取其他信息 | 查看文档 |
createTransaction | 创建订单 | 查看文档 |
confirmTransaction | 确认订单 | 查看文档 |
cancelTransaction | 取消订单 | 查看文档 |
queryTransaction | 查询交易 | 查看文档 |