Currencycloud API v2 JavaScript client
Version: 3.4.0-ea (FORK)
这是来自官方FORK -js">适用于 Currencycloud API v2 的 Javascript SDK。 虽然它试图与上游版本保持同步,但它确实还包括从错误修复到可用性功能的增强和修改。
可在 Currencycloud API 文档 中找到有关每个 API 端点的其他文档。 如果您有任何疑问或需要支持,请通过 development@currencycloud.com 联系他们的开发团队
Installation
这个库分布在 GitHub 包。 为了将它添加为依赖项,请按照以下步骤操作:
- In the same directory as your
package.json
file create or edit an .npmrc
file to include a line specifying GitHub Packages URL
registry=https://npm.pkg.github.com/addario-org
- Configure your project's
package.json
file to include the currencycloud-js-client
dependency
"dependencies": {
"@addario-org/currencycloud-js-client": "3.4.0-ea"
}
- You can then install it in the usual way
$ npm install currencycloud-js-client --save
Supported Node versions
支持最少的 Node 版本是 6.0.0。
Usage
以下示例检索所有可交易货币列表:
var currencyCloud = require('currency-cloud');
currencyCloud.authentication.login({
environment: 'demo',
loginId: 'valid_login_id',
apiKey: 'valid_api_key'
})
.then(currencyCloud.reference.getAvailableCurrencies)
.then(function(res) {
console.log('available currencies: ' + JSON.stringify(res.currencies, null, 2));
})
.then(currencyCloud.balances.find)
.then(function(res) {
console.log('balances: ' + JSON.stringify(res.balances, null, 2));
})
.then(currencyCloud.authentication.logout)
.catch(console.log);
可以在 examples 文件夹中找到更广泛的示例。
Service client
要与各种 Currencycloud 的 API 交互,必须创建一个服务客户端对象; 然后可以通过该对象的相应属性访问特定的 API:
// create service client object
var currencyCloud = require('currency-cloud');
// access authentication API
currencyCloud.authentication.login({
environment: 'demo',
loginId: 'valid_login_id',
apiKey: 'valid_api_key'
})
.then(function() {
// access reference API
return currencyCloud.reference.getBeneficiaryRequiredDetails({
currency: 'EUR',
bankAccountCountry: 'DE'
});
})
.then(console.log)
.then(currencyCloud.authentication.logout);
Currencycloud API 概述< 中列出了支持的 API /a>。
Authentication
在调用 API 函数之前需要进行身份验证。 它的执行方式如下:
var currencyCloud = require('currency-cloud');
currencyCloud.authentication.login({
environment: 'demo', // environment to run API calls against, one of those listed in 'settings' section of package.json
loginId: 'login_id', // login id of the API user, as specified during registration
apiKey: 'api_key' // corresponding API key, obtained upon registration
})
.then(function(token) {
...
});
上述代码检索身份验证令牌,该令牌随所有后续 API 调用一起传递。 如果由于令牌过期导致调用失败,则会尝试重新验证,以便刷新令牌并重试失败的请求。
使用 API 完成后,建议通过调用 currencyCloud.authentication.logout()
关闭会话。
Passing parameters
SDK 函数将参数作为单个对象接受,该对象包含必需参数和可选参数:
var currencyCloud = require('currency-cloud');
currencyCloud.accounts.create({
/* required parameters */
accountName: 'Firma AB',
legalEntityType: 'company',
/* optional parameters */
status: 'enabled',
street: 'Sergels Torg 2',
city: 'Stockholm',
postalCode: '10640',
country: 'SE',
spreadTable: 'no_markup',
identificationType: 'none'
})
.then(console.log);
函数参数以及返回对象和错误是驼峰式的。
Promises
每个 API 调用都是一个异步操作,因此在整个 SDK 中大量使用 Promises/A+ 模式。 每个函数,如果不是同步抛出错误,都会返回一个 then-able promise。
Exponential Backoff & Retry Strategy
通过 Internet 的请求有时会因为看似没有明显原因而失败,SDK 包含一套全面的错误处理功能来帮助解决这些情况。 然而,有时最好的策略就是重试。 这种情况尤其适用于 HTTP 429 - 请求过多 等瞬态错误,但不鼓励将调用包装在 for/while 循环中,因为在某些极端情况下,这可能会触发我们的反 DoS 防御。
从版本 1.14.1 开始,我们引入了带有抖动重试功能的指数退避,我们建议您使用它来安全地处理重试。
retry(fn, [options])
调用 fn 直到返回的 promise 最终实现或被拒绝并出现不同于 TooManyRequestsError
的错误。 可选的options 参数是一个映射到以下值的对象:
- retries: The maximum amount of times to retry the operation. Default is
7
.
- factor: The exponential factor to use. Default is
2
.
- minTimeout: The number of milliseconds before starting the first retry. Default is a random value between
0
and 750
ms.
- maxTimeout: The maximum number of milliseconds between two retries. Default is a random value between
30
and 60
sec.
- randomize: Randomizes the timeouts by multiplying with a factor between
1
and 2
. Default is true
.
- log: Logs retries to console if
true
. Default is false
- name: The name of fn. Helpful for logging and troubleshooting.
fn 函数将接收一个重试函数作为一个参数,每当您想要重试 fn 时都应该调用错误。 重试函数将始终抛出错误。
如果还有重试剩余,它将抛出一个特殊的重试错误,该错误将在内部处理以再次调用 fn。 如果没有重试,它将抛出传递给它的实际错误。
下面介绍了一个典型的用例。 有关详细信息,请参阅Cookbook 示例。
var currencyCloud = require('currency-cloud');
const opts = {
retries: 5, //Retry up to five times before giving up
factor: 2, // Use an exponential wait
minTimeout: Math.random() * 750, // Initial wait in ms
maxTimeout: Math.random() * 30000 + 30000, // Maximum wait period in ms
randomize: true // Apply a random jitter on each iteration
log: true // Log retries to the console
};
let findBalances = () => {
return currencyCloud.retry(
() => {
return currencyCloud.balances.find()
.then(function (res) {
console.log('findBalance: ' + JSON.stringify(res, null, 2));
})
},
opts,
"currencyCloud.balances.find"
);
};
On Behalf Of
一些 API 调用可以代表另一个用户执行(例如,拥有登录用户子帐户的人)。 为此,应将具有相应联系人 ID 值的 onBehalfOf
字段添加到 SDK 函数的参数对象中:
var currencyCloud = require('currency-cloud');
currencyCloud.rates.get({
buyCurrency: 'SEK',
sellurrency: 'GBP',
fixedSide: 'buy',
amount: 1000.5,
onBehalfOf: '8f639ab2-2b85-4327-9eb1-01ee4f0c77bc'
})
.then(console.log);
另一种选择是使用 onBehalfOf(id,承诺)方法; 它需要联系人 ID 和承诺作为参数,并返回给定的承诺解决:
var currencyCloud = require('currency-cloud');
currencyCloud.onBehalfOf('8f639ab2-2b85-4327-9eb1-01ee4f0c77bc', function() {
var beneficiary = {
...
};
var conversion = {
...
};
var payment = {
...
};
return currencyCloud.beneficiaries.create(beneficiary)
.then(function(res) {
payment.beneficiaryId = res.id;
})
.then(function() {
return currencyCloud.conversions.create(conversion);
})
.then(function(res) {
payment.conversionId = res.id
})
.then(function() {
return currencyCloud.payments.create(payment);
});
})
.then(console.log);
Errors
如果 API 调用失败,SDK 函数返回被拒绝的承诺,并将错误包装到 APIerror
类对象中。 更具体地说,它是其中一个类的对象,继承自 APIerror
并表示不同类型的错误。 除了标准的序列化方法外,它们还公开了 toYAML()
方法,该方法将错误对象转换为人类可读的 YAML 字符串:
var currencyCloud = require('currency-cloud');
currencyCloud.balances.get({
currency: 'XYZ'
})
.catch(function(err) {
// the error might be not of APIerror type (e.g connection error)
if(err instanceof currencyCloud.APIerror) {
console.log(err.toYAML());
}
else {
console.log(err);
}
});
/* outputs
BadRequestError
---
platform: node v4.1.1
request:
parameters: {}
verb: GET
url: https://devapi.currencycloud.com/v2/balances/XYZ
response:
statusCode: 400
date: Mon, 09 Nov 2017 15:06:11 GMT
requestId: 2914269054259094430
errors:
- field: currency
code: currency_is_in_invalid_format
message: currency is not a valid ISO 4217 currency code
params:
type: currency
*/
Development
Dependencies
Contributing
我们欢迎来自所有人的拉取请求! 请参阅 CONTRIBUTING
我们真诚地感谢您帮助我们创建用于在世界任何地方转移资金的最佳 API!
Versioning
该项目使用语义版本控制。 您可以安全地表达对主要版本的依赖,并期望所有次要版本和补丁版本向后兼容。
Deprecation Policy
技术发展迅速,我们一直在寻找更好的方式来服务我们的客户。 有时我们需要通过删除不再需要的代码部分来为创新腾出空间。 我们知道这可能会造成破坏,因此我们设计了一项弃用政策来保护我们客户的投资,并允许我们在开发软件时利用现代工具、框架和实践。
弃用意味着我们不鼓励使用某个功能、设计或实践,因为它已被取代或不再被认为是有效或安全的,但我们不会立即将其删除,而是将其标记为 @deprecated 以向后提供兼容性和更新项目的时间。 虽然已弃用的功能会在 SDK 中保留一段时间,但我们建议您将其替换为代码相关部分中解释的推荐替代方案。
我们会在发布后 三个月 后删除弃用的功能。
客户资产的安全对我们来说至关重要,有时我们不得不弃用某些功能,因为它们可能构成安全威胁,或者因为有新的、更安全的方法可用。 在这种情况下,我们保留设置不同弃用期的权利,范围从立即删除到标准的三个月。
一旦某个功能被标记为已弃用,我们将不再开发代码或实施错误修复。 我们只做安全修复。
List of features being deprecated
(No features are currently being deprecated)
Support
我们积极支持最新版本的 SDK。 我们尽最大努力支持上一个版本。 不再支持或维护所有其他版本。
Testing
SDK 的测试依赖于 Mocha 测试框架,Chai断言库和 Nock HTTP 模拟和期望库。 要运行所有测试用例,只需执行:
$ npm run test
SDK 在 ./test/api/fixtures
中包含有效的模拟 HTTP 响应。 如果您想针对实时 API 进行测试,请确保该文件夹中没有 js
文件。 Nock 库将通过记录实时运行的响应来重新生成它们,并在下次执行测试时使用这些响应。
重要提示:请记住更改 ./test/mocks.js
中的 loginId
和 apiKey
属性以使用您的登录 ID 和 API 密钥。
如果您没有有效的登录名或密钥,可以在此处获取它们
Copyright
版权所有 © 2015-2020 Currencycloud。 有关详细信息,请参阅许可证。
版权所有 © modifications 2020, Ed Addario
Currencycloud API v2 JavaScript client
Version: 3.4.0-ea (FORK)
This is a FORK from the official Javascript SDK for v2 of Currencycloud's API. While it tries to keep in sync with the upstream version, it does also include enhancements and modifications ranging from bugfixes to usability features.
Additional documentation for each API endpoint can be found at Currencycloud API documentation. If you have any queries or you require support, please contact their development team at development@currencycloud.com
Installation
This library is distributed on GitHub Packages. In order to add it as a dependency follow these steps:
- In the same directory as your
package.json
file create or edit an .npmrc
file to include a line specifying GitHub Packages URL
registry=https://npm.pkg.github.com/addario-org
- Configure your project's
package.json
file to include the currencycloud-js-client
dependency
"dependencies": {
"@addario-org/currencycloud-js-client": "3.4.0-ea"
}
- You can then install it in the usual way
$ npm install currencycloud-js-client --save
Supported Node versions
The least supported Node version is 6.0.0.
Usage
The following example retrieves all tradeable currencies list:
var currencyCloud = require('currency-cloud');
currencyCloud.authentication.login({
environment: 'demo',
loginId: 'valid_login_id',
apiKey: 'valid_api_key'
})
.then(currencyCloud.reference.getAvailableCurrencies)
.then(function(res) {
console.log('available currencies: ' + JSON.stringify(res.currencies, null, 2));
})
.then(currencyCloud.balances.find)
.then(function(res) {
console.log('balances: ' + JSON.stringify(res.balances, null, 2));
})
.then(currencyCloud.authentication.logout)
.catch(console.log);
More extensive examples can be found in the examples folder.
Service client
To interact with the various Currencycloud's APIs a service client object must be created; then a particular API can be accessed via the corresponding property of this object:
// create service client object
var currencyCloud = require('currency-cloud');
// access authentication API
currencyCloud.authentication.login({
environment: 'demo',
loginId: 'valid_login_id',
apiKey: 'valid_api_key'
})
.then(function() {
// access reference API
return currencyCloud.reference.getBeneficiaryRequiredDetails({
currency: 'EUR',
bankAccountCountry: 'DE'
});
})
.then(console.log)
.then(currencyCloud.authentication.logout);
Supported APIs are listed in the Currencycloud API overview.
Authentication
Prior to calling API functions authentication is required. It is performed as follows:
var currencyCloud = require('currency-cloud');
currencyCloud.authentication.login({
environment: 'demo', // environment to run API calls against, one of those listed in 'settings' section of package.json
loginId: 'login_id', // login id of the API user, as specified during registration
apiKey: 'api_key' // corresponding API key, obtained upon registration
})
.then(function(token) {
...
});
The above code retrieves authentication token, which is passed with all subsequent API calls. If a call fails due to token is expired, then re-authentication is attempted, so that the token is refreshed and the failed request is retried.
When working with API is finished, it is recommended to close the session by calling currencyCloud.authentication.logout()
.
Passing parameters
SDK functions accept arguments as a single object, which holds both required and optional parameters:
var currencyCloud = require('currency-cloud');
currencyCloud.accounts.create({
/* required parameters */
accountName: 'Firma AB',
legalEntityType: 'company',
/* optional parameters */
status: 'enabled',
street: 'Sergels Torg 2',
city: 'Stockholm',
postalCode: '10640',
country: 'SE',
spreadTable: 'no_markup',
identificationType: 'none'
})
.then(console.log);
Function arguments as well as return objects and errors are camelCased.
Promises
Each API call is an asynchronous operation, so Promises/A+ pattern is used heavily throughout the SDK. Every function, if not synchronously throwing an Error, returns a then-able promise.
Exponential Backoff & Retry Strategy
Requests over the internet will fail on occasion for seemingly no apparent reason, and the SDK includes a comprehensive set of error handling capabilities to help troubleshoot those situations. Sometimes however, the best strategy is simply to retry. This is the case particularly with transient errors like HTTP 429 - Too Many Requests, but wrapping calls in for/while loops is discouraged as in some extreme cases this may trigger our anti-DoS defences.
As of version 1.14.1 we have introduced an Exponential Backoff with Jitter retry feature which we recommend you use to safely handle retries.
retry(fn, [options])
Calls fn until the returned promise ends up fulfilled or rejected with an error different than TooManyRequestsError
. The optional options argument is an object which maps to the following values:
- retries: The maximum amount of times to retry the operation. Default is
7
.
- factor: The exponential factor to use. Default is
2
.
- minTimeout: The number of milliseconds before starting the first retry. Default is a random value between
0
and 750
ms.
- maxTimeout: The maximum number of milliseconds between two retries. Default is a random value between
30
and 60
sec.
- randomize: Randomizes the timeouts by multiplying with a factor between
1
and 2
. Default is true
.
- log: Logs retries to console if
true
. Default is false
- name: The name of fn. Helpful for logging and troubleshooting.
The fn function will receive a retry function as an argument that should be called with an error whenever you want to retry fn. The retry function will always throw an error.
If there're retries left, it will throw a special retry error that will be handled internally to call fn again. If there're no retries left, it will throw the actual error passed to it.
A typical use case is presented below. For more information see the Cookbook examples.
var currencyCloud = require('currency-cloud');
const opts = {
retries: 5, //Retry up to five times before giving up
factor: 2, // Use an exponential wait
minTimeout: Math.random() * 750, // Initial wait in ms
maxTimeout: Math.random() * 30000 + 30000, // Maximum wait period in ms
randomize: true // Apply a random jitter on each iteration
log: true // Log retries to the console
};
let findBalances = () => {
return currencyCloud.retry(
() => {
return currencyCloud.balances.find()
.then(function (res) {
console.log('findBalance: ' + JSON.stringify(res, null, 2));
})
},
opts,
"currencyCloud.balances.find"
);
};
On Behalf Of
Some API calls can be executed on behalf of another user (e.g. someone who has a sub-account with the logged in user). For this sake, onBehalfOf
field with a value of corresponding contact id should be added to a parameters object of a SDK function:
var currencyCloud = require('currency-cloud');
currencyCloud.rates.get({
buyCurrency: 'SEK',
sellurrency: 'GBP',
fixedSide: 'buy',
amount: 1000.5,
onBehalfOf: '8f639ab2-2b85-4327-9eb1-01ee4f0c77bc'
})
.then(console.log);
Another option is to run a bunch of API calls using onBehalfOf(id, promise)
method; it expects contact id and a promise as parameters and returns the given promise resolved:
var currencyCloud = require('currency-cloud');
currencyCloud.onBehalfOf('8f639ab2-2b85-4327-9eb1-01ee4f0c77bc', function() {
var beneficiary = {
...
};
var conversion = {
...
};
var payment = {
...
};
return currencyCloud.beneficiaries.create(beneficiary)
.then(function(res) {
payment.beneficiaryId = res.id;
})
.then(function() {
return currencyCloud.conversions.create(conversion);
})
.then(function(res) {
payment.conversionId = res.id
})
.then(function() {
return currencyCloud.payments.create(payment);
});
})
.then(console.log);
Errors
If an API call fails, the SDK function returns rejected promise with the error wrapped into APIerror
class object. More specifically, it's an object of one of the classes, inheriting from APIerror
and representing different types of errors. Apart from standard serialization methods they expose toYAML()
method, which converts error object to human-readable YAML string:
var currencyCloud = require('currency-cloud');
currencyCloud.balances.get({
currency: 'XYZ'
})
.catch(function(err) {
// the error might be not of APIerror type (e.g connection error)
if(err instanceof currencyCloud.APIerror) {
console.log(err.toYAML());
}
else {
console.log(err);
}
});
/* outputs
BadRequestError
---
platform: node v4.1.1
request:
parameters: {}
verb: GET
url: https://devapi.currencycloud.com/v2/balances/XYZ
response:
statusCode: 400
date: Mon, 09 Nov 2017 15:06:11 GMT
requestId: 2914269054259094430
errors:
- field: currency
code: currency_is_in_invalid_format
message: currency is not a valid ISO 4217 currency code
params:
type: currency
*/
Development
Dependencies
Contributing
We welcome pull requests from everyone! Please see CONTRIBUTING
Our sincere thanks for helping us create the best API for moving money anywhere around the world!
Versioning
This project uses semantic versioning. You can safely express a dependency on a major version and expect all minor and patch versions to be backwards compatible.
Deprecation Policy
Technology evolves quickly and we are always looking for better ways to serve our customers. From time to time we need to make room for innovation by removing sections of code that are no longer necessary. We understand this can be disruptive and consequently we have designed a Deprecation Policy that protects our customers' investment and that allows us to take advantage of modern tools, frameworks and practices in developing software.
Deprecation means that we discourage the use of a feature, design or practice because it has been superseded or is no longer considered efficient or safe but instead of removing it immediately, we mark it as @deprecated to provide backwards compatibility and time for you to update your projects. While the deprecated feature remains in the SDK for a period of time, we advise that you replace it with the recommended alternative which is explained in the relevant section of the code.
We remove deprecated features after three months from the time of announcement.
The security of our customers' assets is of paramount importance to us and sometimes we have to deprecate features because they may pose a security threat or because new, more secure, ways are available. On such occasions we reserve the right to set a different deprecation period which may range from immediate removal to the standard three months.
Once a feature has been marked as deprecated, we no longer develop the code or implement bug fixes. We only do security fixes.
List of features being deprecated
(No features are currently being deprecated)
Support
We actively support the latest version of the SDK. We support the immediate previous version on best-efforts basis. All other versions are no longer supported nor maintained.
Testing
Testing of the SDK relies on the Mocha test framework, Chai assertions library and Nock HTTP mocking and expectations library. To run all test cases simply execute:
$ npm run test
The SDK includes valid mocked HTTP responses in ./test/api/fixtures
. If you would like to test against the live API, please ensure there are no js
files in that folder. The Nock library will regenerate them by recording the responses from the live run and use those next time the tests are executed.
IMPORTANT: Remember to change the loginId
and apiKey
properties in ./test/mocks.js
to use your login ID and API key.
If you don't have a valid login or key, you can get them here
Copyright
Copyright © 2015-2020 Currencycloud. See LICENSE for details.
Copyright © modifications 2020, Ed Addario