createExchange

POST: /amsin/api/v1/business/fund/createExchange

需要签名验签

集成商可调用此接口发起外汇交割请求。万里汇支持两种外汇交割场景:

  • 远期外汇。用户可以获得一段时间后的稳定外汇汇率。此场景下,createExchange接口为异步。万里汇响应给集成商的结果为API调用结果而非外汇交割结果。集成商需调用inquiryExchange接口查询是否外汇交割到户,或等待万里汇使用notifyExchange接口发送通知。
  • 即期外汇。用户可以获得当下的即时外汇汇率。此场景下,createExchange接口响应外汇交割到户的结果。

接口结构

万里汇接口报文结构包括:请求头,请求体。关于头信息,详见:

请求参数

字段名

数据类型

是否必填

描述

customerId

字符串

是(有条件必填)

由万里汇定义、用于唯一标识某万里汇账户。

更多信息:

  • customerIdaccessToken 不能同时为空
  • 字段最大长度:64

accessToken

字符串

是(有条件必填)

用于OAuth校验的访问令牌

更多信息:

  • customerIdaccessToken 不能同时为空
  • 字段最大长度:64

exchangeRequestId

字符串

由集成商定义,代表本次外汇交割到户请求的唯一ID。

更多信息:

quote

Quote 对象

是(有条件必填)

本次外汇交割到户请求的外汇汇率信息。仅在锁汇场景下,此字段为必填。

sell

QuoteAmount 对象

卖出外汇金额

更多信息:

  • sell.valuebuy.value字段不能同时为空。

buy

QuoteAmount 对象

买入外汇金额

更多信息:

  • sell.valuebuy.value字段不能同时为空。

exchangeMode

字符串

外汇交割模式。取值范围:

  • REALTIME:实时交割
  • APPOINTED:指定日期交割

关于字段枚举值,详见: exchangeMode

exchangeTradeType

字符串

外汇交割类型。取值范围:

  • SPOT:即时汇率
  • FORWARD:远期汇率
  • UNFUNDED_SPOT: 指该笔外汇交易类型为资金不充足的即期交易,使用的是远期汇率

关于字段枚举值,详见:exchangeTradeType

exchangeUnfundedInfo

ExchangeForwardInfo 对象

是(有条件必填)

外汇交割相关信息,exchangeTradeType取值为FORWARDUNFUNDED_SPOT时,此字段必填

exchangeOrderAddition

ExchangeQuoteAddition 对象

外汇交割附加信息,如客户端的订单ID等。

exchangeRequestTime

字符串

请求的时间

更多信息:

  • 此字段采用ISO 8601 标准时间戳。如:2018-09-03T00:00:00+08:00,或2019-01-01T01:01:01Z(UTC时间)

响应参数

字段名

数据类型

是否必填

描述

result

Result 对象

代表接口调用结果

exchangeId

字符串

由万里汇定义的,本次外汇交割到户请求的唯一ID。

更多信息:

  • 字段最大长度:64

exchangeRequestId

字符串

由集成商定义,代表本次外汇交割到户请求的唯一ID。

更多信息:

sell

QuoteAmount 对象

卖出外汇金额

buy

QuoteAmount 对象

买入外汇金额

exchangeCreateTime

Datetime 对象

外汇交割到户请求的发起时间

更多信息:

  • 此字段采用ISO 8601 标准时间戳。如:2018-09-03T00:00:00+08:00,或2019-01-01T01:01:01Z(UTC时间)

exchangeFinishTime

Datetime 对象

外汇交割到户请求的完成时间

更多信息:

  • 此字段采用ISO 8601 标准时间戳。如:2018-09-03T00:00:00+08:00,或2019-01-01T01:01:01Z(UTC时间)

quote

Quote 对象

本次外汇交割到户请求的外汇汇率信息

exchangeMode

字符串

外汇交割模式。取值范围:

  • REALTIME:实时交割
  • APPOINTED:指定日期交割

关于字段枚举值,详见: exchangeMode

exchangeTradeType

字符串

外汇交割类型。取值范围:

  • SPOT:即时汇率
  • FORWARD:远期汇率

关于字段枚举值,详见:exchangeTradeType

exchangeUnfundedInfo

ExchangeForwardInfo 对象

是(有条件必填)

外汇交割信息,当exchangeTradeType取值为FORWARDUNFUNDED_SPOT时此字段为必填

响应处理

集成商调用接口后,万里汇响应集成商API调用结果。result.resultStatus字段取值范围为:

result.resultStatus

描述

S

API请求成功。

远期外汇交割场景:

  • 如果result.resultStatus 为 S,表示万里汇已接受本次API请求,远期外汇交易正在处理中。调用inquiryDeal以查询远期外汇交易结果。

即期外汇交割场景:

  • 如果result.resultStatus 为 S,表示本次外汇交割请求成功。

F

API请求失败。

失败原因参见结果码(即result.resultCoderesult.resultMessage

U

API响应结果为UNKNOWN(未知)时,集成商需调用inquiryExchange接口以检查外汇交割请求状态。

结果码

result.resultCode

系统结果码

resultCode

resultStatus

resultMessage

处理建议

SUCCESS

S

Success

PARAM_ILLEGAL

F

Illegal parameters exist. For example, a non-numeric input, or an invalid date.

参考API文档页面,确认请求头和传参是否正确

PROCESS_FAIL

F

A general business failure occurred. Do not retry.

需要人工介入,联系万里汇技术支持以解决此问题

UNKNOWN_EXCEPTION

U

API failed due to unknown reason.

服务器错误,若稍后重试问题依旧,联系万里汇技术支持以解决问题

REQUEST_TRAFFIC_EXCEED_LIMIT

U

The request traffic exceeds the limit.

重试,若问题依旧,联系万里汇技术支持

INVALID_API

F

The called API is invalid or not active.

确认是否调用正确的API

INVALID_CLIENT

F

The client is invalid.

Client ID不存在或无效

INVALID_SIGNATURE

F

The signature is invalid.

确认请求正确加签,具体参见:

METHOD_NOT_SUPPORTED

F

The server does not implement the requested HTTP method.

确认HTTP请求方法为POST

业务结果码

resultCode

resultStatus

resultMessage

处理建议

PROCESSING

S

The payment order is being processed.

订单已创建,处理中。调用inquiryExchange来获取结果或等到万里汇使用notifyExchange发送结果通知

BALANCE_INSUFFICIENT

F

The balance is insufficient for the exchange.

仅出现于即期外汇交易场景。确认余额充足后重试

AUTHORIZATION_NOT_EXIST

F

The authorization does not exist.

当前授权关系不存在,请联系万里汇技术支持检查授权关系

UN_SUPPORT_BUSINESS

F

Unsupported business.

包含无效参数(如货币代码错误),使用正确的参数重试

QUOTE_EXPIRED

F

The quote is expired.

调用createQuote接口来获取新汇率报价,并使用新汇率报价完成外汇请求

FX_RELATED_ORDER_NOT_EXIST

F

The exchange order does not exist.

仅出现于远期外汇交割场景。确认dealId正确后重试

CURRENCY_NOT_SUPPORT

F

The currency is not supported.

确认币种信息正确后重试

CONTRACT_CHECK_FAIL

F

The contract check has failed.

检查合约状态后重试

范例

请求

请求体范例

即期汇率场景

copy
{
  "customerId": "*****",
  "exchangeRequestId": "*****",
  "sell": {
    "currency": "EUR",
    "value": 23333
  },
  "buy": {
    "currency": "GBP",
    "value": 19601
  },
  "exchangeMode": "APPOINTED",
  "exchangeTradeType": "SPOT",
  "exchangeOrderAddition": {
    "referenceOrderId": "*****",
    "exchangeMemo": ""
  },
  "exchangeRequestTime": "{{$isoTimestamp}}",
  "quote": {
    "quoteCurrencyPair": "EUR/GBP",
    "quoteExpiryTime": "2022-08-25T10:17:08Z",
    "quoteId": "*****",
    "quotePrice": "0.84005",
    "quoteStartTime": "2022-08-25T10:16:38Z"
  }
}

远期汇率场景

copy
{
  "customerId": "*****",
  "exchangeRequestId": "*****",
  "sell": {
    "currency": "USD",
    "value": 1000
  },
  "buy": {
    "currency": "EUR",
    "value": 995
  },
  "exchangeMode": "APPOINTED",
  "exchangeTradeType": "FORWARD",
  "exchangeOrderAddition": {
    "exchangeMemo": "exchange-test",
    "referenceOrderId": "*****"
  },
  "exchangeRequestTime": "2022-06-28T02:58:47Z",
  "exchangeForwardInfo": {
    "dealId": "*****"
  }
}

请求代码范例

copy
var jsonStr="{\"customerId\":\"*****\",\"exchangeRequestId\":\"*****\",\"sell\":{\"currency\":\"EUR\",\"value\":215},\"buy\":{\"currency\":\"USD\",\"value\":231},\"exchangeMode\":\"APPOINTED\",\"exchangeTradeType\":\"SPOT\",\"exchangeOrderAddition\":{\"referenceOrderId\":\"*****\",\"exchangeMemo\":\"exchange-test-memo\"},\"exchangeRequestTime\":\"2022-05-16T08:55:08Z\",\"quote\":{\"quoteCurrencyPair\":\"EUR/USD\",\"quoteExpiryTime\":\"2022-05-16T09:08:51Z\",\"quoteId\":\"*****\",\"quotePrice\":\"1.07461952\",\"quoteStartTime\":\"2022-05-16T08:53:51Z\"}}";
var client = new RestClient("http://{domain_name}.com/amsin/api/v1/business/fund/createExchange");
var request = new RestRequest(Method.POST);
request.AddHeader("client-id","*****");
request.AddHeader("request-time","2022-05-17T11:19:20+08:00");
request.AddHeader("Content-Type","application/json");
request.AddHeader("signature","algorithm=RSA256,keyVersion=1,signature=RckSOIrxy%2FKqC%2FZQOO0t74U9U4TFVYKmW%2FZflFRut7W1hipos3NLBGdpzbulcc5Q7XwZP1t3qgTZMFrC%2FlzOQCOsBhUgelvEAuACu49PEGiAus8sU%2FFJa1HOIUmst3oWjLT%2BDqY083mR7jVwc5O2JYP08wNCLu55PFZtXHBUfwEAYoZInhgRoLtQTr%2F7Bphd7L9cS3xD3tluxbgkcaFr7NQVrfWJuQKp%2BFrabo6xZr%2FRHZRd%2FijALuUYYjXH92n4VFwSXSO%2B%2BUBVPoGyWWz1q3QJ2tHNVU7wpc3wtCwwB76pNfGTbJit%2BdylGU8O5UkW3TwSkNnpzepRABM8bBQpgQ%*****");
request.AddParameter("application/json; charset=utf-8", jsonStr, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
copy
url = "http://{domain_name}.com//amsin/api/v1/business/account/createExchange"
headers = {
    "client-id": "*****",
    "request-time": "2022-05-17T11:19:20+08:00",
    "Content-Type": "application/json",
    "signature": "algorithm=RSA256,keyVersion=1,signature=RckSOIrxy%2FKqC%2FZQOO0t74U9U4TFVYKmW%2FZflFRut7W1hipos3NLBGdpzbulcc5Q7XwZP1t3qgTZMFrC%2FlzOQCOsBhUgelvEAuACu49PEGiAus8sU%2FFJa1HOIUmst3oWjLT%2BDqY083mR7jVwc5O2JYP08wNCLu55PFZtXHBUfwEAYoZInhgRoLtQTr%2F7Bphd7L9cS3xD3tluxbgkcaFr7NQVrfWJuQKp%2BFrabo6xZr%2FRHZRd%2FijALuUYYjXH92n4VFwSXSO%2B%2BUBVPoGyWWz1q3QJ2tHNVU7wpc3wtCwwB76pNfGTbJit%2BdylGU8O5UkW3TwSkNnpzepRABM8bBQpgQ%*****"
}
datas ={"customerId":"*****","exchangeRequestId":"*****","sell":{"currency":"EUR","value":215},"buy":{"currency":"USD","value":231},"exchangeMode":"APPOINTED","exchangeTradeType":"SPOT","exchangeOrderAddition":{"referenceOrderId":"*****","exchangeMemo":"exchange-test-memo"},"exchangeRequestTime":"2022-05-16T08:55:08Z","quote":{"quoteCurrencyPair":"EUR/USD","quoteExpiryTime":"2022-05-16T09:08:51Z","quoteId":"*****","quotePrice":"1.07461952","quoteStartTime":"2022-05-16T08:53:51Z"}}
res = requests.post(url=url, data=json.dumps(datas), headers=headers)
copy
CloseableHttpClient client = HttpClientBuilder.create().build();
HttpPost httpPost = new HttpPost("http://{domain_name}.com//amsin/api/v1/business/fund/createExchange");
httpPost.addHeader("client-id", "*****");
httpPost.addHeader("request-time", "2022-05-17T11:19:20+08:00");
httpPost.addHeader("signature","algorithm=RSA256,keyVersion=1,signature=RckSOIrxy%2FKqC%2FZQOO0t74U9U4TFVYKmW%2FZflFRut7W1hipos3NLBGdpzbulcc5Q7XwZP1t3qgTZMFrC%2FlzOQCOsBhUgelvEAuACu49PEGiAus8sU%2FFJa1HOIUmst3oWjLT%2BDqY083mR7jVwc5O2JYP08wNCLu55PFZtXHBUfwEAYoZInhgRoLtQTr%2F7Bphd7L9cS3xD3tluxbgkcaFr7NQVrfWJuQKp%2BFrabo6xZr%2FRHZRd%2FijALuUYYjXH92n4VFwSXSO%2B%2BUBVPoGyWWz1q3QJ2tHNVU7wpc3wtCwwB76pNfGTbJit%2BdylGU8O5UkW3TwSkNnpzepRABM8bBQpgQ%*****" );
httpPost.addHeader("Content-Type","application/json");
StringEntity entity = new StringEntity("{\"customerId\":\"*****\",\"exchangeRequestId\":\"*****\",\"sell\":{\"currency\":\"EUR\",\"value\":215},\"buy\":{\"currency\":\"USD\",\"value\":231},\"exchangeMode\":\"APPOINTED\",\"exchangeTradeType\":\"SPOT\",\"exchangeOrderAddition\":{\"referenceOrderId\":\"*****\",\"exchangeMemo\":\"exchange-test-memo\"},\"exchangeRequestTime\":\"2022-05-16T08:55:08Z\",\"quote\":{\"quoteCurrencyPair\":\"EUR/USD\",\"quoteExpiryTime\":\"2022-05-16T09:08:51Z\",\"quoteId\":\"*****\",\"quotePrice\":\"1.07461952\",\"quoteStartTime\":\"2022-05-16T08:53:51Z\"}}");
httpPost.setEntity(entity);
CloseableHttpResponse response = client.execute(httpPost);
copy
var jsonStr="{\"customerId\":\"*****\",\"exchangeRequestId\":\"*****\",\"sell\":{\"currency\":\"EUR\",\"value\":215},\"buy\":{\"currency\":\"USD\",\"value\":231},\"exchangeMode\":\"APPOINTED\",\"exchangeTradeType\":\"SPOT\",\"exchangeOrderAddition\":{\"referenceOrderId\":\"*****\",\"exchangeMemo\":\"exchange-test-memo\"},\"exchangeRequestTime\":\"2022-05-16T08:55:08Z\",\"quote\":{\"quoteCurrencyPair\":\"EUR/USD\",\"quoteExpiryTime\":\"2022-05-16T09:08:51Z\",\"quoteId\":\"*****\",\"quotePrice\":\"1.07461952\",\"quoteStartTime\":\"2022-05-16T08:53:51Z\"}}";
var client = "http://{domain_name}.com/amsin/api/v1/business/fund/createExchange";
var xhr = new XMLHttpRequest;
xhr.open("POST",client,true);
xhr.setRequestHeader("client-id","*****");
xhr.setRequestHeader("request-time","2022-05-17T11:19:20+08:00");
xhr.setRequestHeader("Content-Type","application/json");
xhr.setRequestHeader("signature","algorithm=RSA256,keyVersion=1,signature=RckSOIrxy%2FKqC%2FZQOO0t74U9U4TFVYKmW%2FZflFRut7W1hipos3NLBGdpzbulcc5Q7XwZP1t3qgTZMFrC%2FlzOQCOsBhUgelvEAuACu49PEGiAus8sU%2FFJa1HOIUmst3oWjLT%2BDqY083mR7jVwc5O2JYP08wNCLu55PFZtXHBUfwEAYoZInhgRoLtQTr%2F7Bphd7L9cS3xD3tluxbgkcaFr7NQVrfWJuQKp%2BFrabo6xZr%2FRHZRd%2FijALuUYYjXH92n4VFwSXSO%2B%2BUBVPoGyWWz1q3QJ2tHNVU7wpc3wtCwwB76pNfGTbJit%2BdylGU8O5UkW3TwSkNnpzepRABM8bBQpgQ%*****");
xhr.send(jsonStr);

响应

响应体范例

即期汇率场景

copy
{
  "buy": {
    "currency": "GBP",
    "value": 19601
  },
  "exchangeCreateTime": "2022-08-25T10:16:49Z",
  "exchangeFinishTime": "2022-08-25T10:16:57Z",
  "exchangeId": "*****",
  "exchangeMode": "APPOINTED",
  "exchangeRequestId": "*****",
  "exchangeTradeType": "SPOT",
  "quote": {
    "quoteCurrencyPair": "EUR/GBP",
    "quoteExpiryTime": "2022-08-25T10:17:08Z",
    "quoteId": "*****",
    "quotePrice": "0.84005",
    "quoteStartTime": "2022-08-25T10:16:38Z"
  },
  "result": {
    "resultStatus": "S",
    "resultCode": "SUCCESS",
    "resultMessage": "success"
  },
  "sell": {
    "currency": "EUR",
    "value": 23333
  }
}

远期汇率场景

copy
{
  "customerId": "*****",
  "exchangeRequestId": "*****",
  "sell": {
    "currency": "CNH",
    "value": 1000
  },
  "buy": {
    "currency": "EUR"
  },
  "exchangeMode": "APPOINTED",
  "exchangeTradeType": "FORWARD",
  "exchangeOrderAddition": {
    "referenceOrderId": "*****",
    "exchangeMemo": "*****"
  },
  "exchangeRequestTime": "2022-08-26T10:16:57Z",
  "exchangeForwardInfo": {
    "dealId": "*****"
  }
}

@2024 WorldFirst