mirror of
https://github.com/valitydev/swag-wallets-webhook-events.git
synced 2024-11-06 01:55:18 +00:00
Pull current spec and clean it up
Also setup CI and CD to GH pages through GH actions.
This commit is contained in:
parent
3eedc0e4c8
commit
4300979ed5
23
.github/workflows/build.yaml
vendored
Normal file
23
.github/workflows/build.yaml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
name: build
|
||||
on:
|
||||
- pull_request
|
||||
|
||||
env:
|
||||
NODEJS_VERSION: '16'
|
||||
|
||||
jobs:
|
||||
bundle:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ env.NODEJS_VERSION }}
|
||||
cache: npm
|
||||
- run: npm install
|
||||
- name: Bundle specification
|
||||
run: npm run build
|
||||
- name: Validate specification
|
||||
run: npm run test
|
@ -1 +1 @@
|
||||
# Empayre Wallets · Webhook Events API Specification
|
||||
# Vality Wallets · Webhook Events API Specification
|
||||
|
58
gulpfile.js
Normal file
58
gulpfile.js
Normal file
@ -0,0 +1,58 @@
|
||||
var gulp = require('gulp');
|
||||
var util = require('gulp-util')
|
||||
var gulpConnect = require('gulp-connect');
|
||||
var connect = require('connect');
|
||||
var cors = require('cors');
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var portfinder = require('portfinder');
|
||||
var swaggerRepo = require('swagger-repo');
|
||||
|
||||
var DIST_DIR = 'dist';
|
||||
|
||||
gulp.task('edit', gulp.series(
|
||||
function (cb) {
|
||||
exec('npm run bundle-swagger-ui', function (err, stdout, stderr) {
|
||||
console.log(stderr);
|
||||
cb(err);
|
||||
});
|
||||
},
|
||||
function () {
|
||||
portfinder.getPort({ port: 5000 }, function (err, port) {
|
||||
var app = connect();
|
||||
app.use(swaggerRepo.swaggerEditorMiddleware());
|
||||
app.listen(port);
|
||||
util.log(util.colors.green('swagger-editor started http://localhost:' + port));
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
gulp.task('build', function (cb) {
|
||||
exec('npm run build', function (err, stdout, stderr) {
|
||||
console.log(stderr);
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('reload', gulp.parallel('build', function () {
|
||||
gulp.src(DIST_DIR).pipe(gulpConnect.reload())
|
||||
}));
|
||||
|
||||
gulp.task('watch', function () {
|
||||
gulp.watch(['spec/**/*', 'web/**/*'], gulp.series(['reload']));
|
||||
});
|
||||
|
||||
gulp.task('serve', gulp.parallel('build', 'watch', 'edit', function () {
|
||||
portfinder.getPort({ port: 3000 }, function (err, port) {
|
||||
gulpConnect.server({
|
||||
root: [DIST_DIR],
|
||||
livereload: true,
|
||||
port: port,
|
||||
middleware: function (gulpConnect, opt) {
|
||||
return [
|
||||
cors()
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
}));
|
15889
package-lock.json
generated
Normal file
15889
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
28
package.json
Normal file
28
package.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "swag-wallets-webhook-openapi-spec",
|
||||
"version": "0.0.1",
|
||||
"dependencies": {
|
||||
"bower": "^1.7.7",
|
||||
"connect": "^3.4.1",
|
||||
"cors": "^2.7.1",
|
||||
"gulp-connect": "^4.2.0",
|
||||
"gulp-util": "^3.0.8",
|
||||
"json-merge-patch": "^0.2.3",
|
||||
"npm": "^8.1.3",
|
||||
"portfinder": "^1.0.3",
|
||||
"shelljs": "^0.7.0",
|
||||
"swagger-repo": "^1.5.1",
|
||||
"swagger-ui": "^2.1.4"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "node ./scripts/build.js",
|
||||
"bundle-swagger-ui": "node ./scripts/bundle-swagger-ui.js",
|
||||
"swagger": "swagger-repo",
|
||||
"test": "swagger-repo validate",
|
||||
"start": "gulp serve"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "github:gulpjs/gulp"
|
||||
}
|
||||
}
|
165
pom.xml
Normal file
165
pom.xml
Normal file
@ -0,0 +1,165 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>dev.vality</groupId>
|
||||
<artifactId>parent</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>swag-wallets-webhook-events</artifactId>
|
||||
<version>SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>swag-wallets-webhook-events</name>
|
||||
<description>Generates jar artifact containing compiled swagger classes based on generated swagger yaml files
|
||||
</description>
|
||||
|
||||
<properties>
|
||||
<default.package>dev.vality.swag.wallets.webhook.events</default.package>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<swagger-annotations-version>1.5.21</swagger-annotations-version>
|
||||
<jodatime-version>2.7</jodatime-version>
|
||||
<maven-plugin-version>1.0.0</maven-plugin-version>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<jetty-version>9.2.15.v20160210</jetty-version>
|
||||
<slf4j-version>1.7.21</slf4j-version>
|
||||
<junit-version>4.12</junit-version>
|
||||
<servlet-api-version>2.5</servlet-api-version>
|
||||
<springfox-version>3.0.0</springfox-version>
|
||||
<jackson-version>2.11.3</jackson-version>
|
||||
<jackson-threetenbp-version>2.6.4</jackson-threetenbp-version>
|
||||
<spring-version>5.3.1</spring-version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-log4j12</artifactId>
|
||||
<version>${slf4j-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--Spring dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
<version>${spring-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!--SpringFox dependencies-->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${springfox-version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${springfox-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
<version>${jackson-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit-version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
<version>${servlet-api-version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.annotation</groupId>
|
||||
<artifactId>javax.annotation-api</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</dependency>
|
||||
<!-- Bean Validation API support -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
<version>1.1.0.Final</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-codegen-maven-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>generate</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
|
||||
<inputSpec>web_deploy/swagger.yaml</inputSpec>
|
||||
<configOptions>
|
||||
<dateLibrary>java8</dateLibrary>
|
||||
</configOptions>
|
||||
|
||||
<language>spring</language>
|
||||
<library>spring-mvc</library>
|
||||
|
||||
<apiPackage>${default.package}.api</apiPackage>
|
||||
<modelPackage>${default.package}.model</modelPackage>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
17
scripts/build.js
Executable file
17
scripts/build.js
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
var TARGET_DIR = 'dist'
|
||||
if (process.argv[2]) {
|
||||
TARGET_DIR = process.argv[2]
|
||||
}
|
||||
|
||||
require('shelljs/global');
|
||||
set('-e');
|
||||
|
||||
mkdir('-p', TARGET_DIR);
|
||||
|
||||
cp('-R', 'web/*', TARGET_DIR + '/');
|
||||
|
||||
exec('npm run swagger bundle -- -o ' + TARGET_DIR + '/swagger.json');
|
||||
exec('npm run swagger bundle -- --yaml -o ' + TARGET_DIR + '/swagger.yaml');
|
18
scripts/bundle-swagger-ui.js
Executable file
18
scripts/bundle-swagger-ui.js
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
var Path = require('path');
|
||||
|
||||
var TARGET_DIR = 'dist'
|
||||
if (process.argv[2]) {
|
||||
TARGET_DIR = process.argv[2]
|
||||
}
|
||||
|
||||
require('shelljs/global');
|
||||
set('-e');
|
||||
|
||||
mkdir('-p', TARGET_DIR);
|
||||
|
||||
var SWAGGER_UI_DIST = Path.dirname(require.resolve('swagger-ui'));
|
||||
rm('-rf', TARGET_DIR + '/swagger-ui/')
|
||||
cp('-R', SWAGGER_UI_DIST, TARGET_DIR + '/swagger-ui/')
|
||||
sed('-i', 'http://petstore.swagger.io/v2/swagger.json', '../swagger.json', TARGET_DIR + '/swagger-ui/index.html')
|
31
scripts/plugins/x-merge-properties.js
Normal file
31
scripts/plugins/x-merge-properties.js
Normal file
@ -0,0 +1,31 @@
|
||||
var jpointer = require('json-pointer');
|
||||
var mergePatch = require('json-merge-patch');
|
||||
|
||||
module.exports = {
|
||||
pathExpression: '$..["x-merge-properties"]',
|
||||
init: function(swagger) {
|
||||
console.log('* x-merge-properties plugin');
|
||||
},
|
||||
process: function(parent, name, jsonpath, swagger) {
|
||||
var value = parent[name];
|
||||
if (!Array.isArray(value)) {
|
||||
throw Error('x-merge-properties argument should be array at ' + jsonpath);
|
||||
}
|
||||
let required = [];
|
||||
let properties = {};
|
||||
value.forEach(function(obj) {
|
||||
if (obj.$ref && (typeof obj.$ref === 'string')) {
|
||||
obj = jpointer.get(swagger, obj.$ref.substring(1));
|
||||
}
|
||||
if (typeof obj !== 'object') throw Error('Can\'t merge non-object values at ' + jsonpath);
|
||||
required = required.concat(obj.required || []);
|
||||
properties = mergePatch.apply(properties, obj.properties || {});
|
||||
});
|
||||
delete parent[name];
|
||||
parent.required = required;
|
||||
parent.properties = properties;
|
||||
},
|
||||
finish: function(swagger) {
|
||||
// TODO: cleanup unused $refs
|
||||
},
|
||||
}
|
28
scripts/plugins/x-rebillyMerge.js
Normal file
28
scripts/plugins/x-rebillyMerge.js
Normal file
@ -0,0 +1,28 @@
|
||||
var jpointer = require('json-pointer');
|
||||
var mergePatch = require('json-merge-patch');
|
||||
|
||||
module.exports = {
|
||||
pathExpression: '$..["x-rebillyMerge"]',
|
||||
init: function(swagger) {
|
||||
console.log('* x-rebillyMerge plugin');
|
||||
},
|
||||
process: function(parent, name, jsonpath, swagger) {
|
||||
var value = parent[name];
|
||||
if (!Array.isArray(value)) {
|
||||
throw Error('x-rebillyMerge argument should be array at ' + jsonpath);
|
||||
}
|
||||
let res = null;
|
||||
value.forEach(function(obj) {
|
||||
if (typeof obj !== 'object') throw Error('Can\'t merge non-object values at ' + jsonpath);
|
||||
if (obj.$ref && (typeof obj.$ref === 'string')) {
|
||||
obj = jpointer.get(swagger, obj.$ref.substring(1));
|
||||
}
|
||||
res = mergePatch.apply(res, obj);
|
||||
});
|
||||
delete parent[name];
|
||||
Object.assign(parent, res);
|
||||
},
|
||||
finish: function(swagger) {
|
||||
// TODO: cleanup unused $refs
|
||||
},
|
||||
}
|
24
spec/README.md
Normal file
24
spec/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
## Global headers
|
||||
|
||||
In order to minimize duplications you can use `headers` global object (similar to `definitions`, `responses`).
|
||||
During build process all references to global `headers` will be inlined and `headers` will be removed form resulting spec so spec will be valid (global `headers` is not allowed by Swagger spec):
|
||||
|
||||
Example:
|
||||
```yaml
|
||||
...
|
||||
headers:
|
||||
Rate-Limit-Limit:
|
||||
description: The number of allowed requests in the current period
|
||||
type: integer
|
||||
...
|
||||
paths:
|
||||
/api-keys:
|
||||
get:
|
||||
summary: Retrieve a list of api keys
|
||||
responses:
|
||||
200:
|
||||
description: A list of api keys was retrieved successfully
|
||||
headers:
|
||||
Rate-Limit-Limit:
|
||||
$ref: "#/headers/Rate-Limit-Limit"
|
||||
```
|
24
spec/definitions/Account.yaml
Normal file
24
spec/definitions/Account.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
description: Данные счета
|
||||
type: object
|
||||
required:
|
||||
- currency
|
||||
- identity
|
||||
properties:
|
||||
id:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/AccountID'
|
||||
createdAt:
|
||||
description: Дата и время создания счета
|
||||
type: string
|
||||
format: date-time
|
||||
|
||||
currency:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/CurrencyID'
|
||||
identity:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/IdentityID'
|
||||
accountNumber:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/AccountNumber'
|
||||
|
3
spec/definitions/AccountID.yaml
Normal file
3
spec/definitions/AccountID.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Идентификатор счета
|
||||
type: string
|
||||
example: tZ0jUmlsV0
|
4
spec/definitions/AccountNumber.yaml
Normal file
4
spec/definitions/AccountNumber.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
description: Номер счета
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1430000
|
16
spec/definitions/Asset.yaml
Normal file
16
spec/definitions/Asset.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
description: |
|
||||
Объём денежных средств
|
||||
type: object
|
||||
required:
|
||||
- amount
|
||||
- currency
|
||||
properties:
|
||||
amount:
|
||||
description: |
|
||||
Сумма денежных средств в минорных единицах, например, в копейках
|
||||
type: integer
|
||||
format: int64
|
||||
example: 1430000
|
||||
currency:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/CurrencyID'
|
26
spec/definitions/BankCard.yaml
Normal file
26
spec/definitions/BankCard.yaml
Normal file
@ -0,0 +1,26 @@
|
||||
description: Данные банковской карты
|
||||
allOf:
|
||||
- $ref: '#/definitions/DestinationResource'
|
||||
- type: object
|
||||
required:
|
||||
- cardNumberMask
|
||||
- paymentSystem
|
||||
properties:
|
||||
cardNumberMask:
|
||||
description: Маскированый номер карты
|
||||
type: string
|
||||
pattern: '^\d{6,8}\*+\d{2,4}$'
|
||||
bin:
|
||||
description: BIN банка-эмитента карты
|
||||
type: string
|
||||
pattern: '^\d{6,8}$'
|
||||
lastDigits:
|
||||
description: Последние цифры номера карты
|
||||
type: string
|
||||
pattern: '^\d{2,4}$'
|
||||
paymentSystem:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/BankCardPaymentSystem'
|
||||
tokenProvider:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/BankCardTokenProvider'
|
12
spec/definitions/BankCardPaymentSystem.yaml
Normal file
12
spec/definitions/BankCardPaymentSystem.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
description: Платежная система
|
||||
type: string
|
||||
# enum:
|
||||
# - visa
|
||||
# - mastercard
|
||||
# - dankort
|
||||
# - amex
|
||||
# - dinersclub
|
||||
# - discover
|
||||
# - unionpay
|
||||
# - jcb
|
||||
# - nspkmir
|
6
spec/definitions/BankCardTokenProvider.yaml
Normal file
6
spec/definitions/BankCardTokenProvider.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
description: Провайдер платежных токенов
|
||||
type: string
|
||||
enum:
|
||||
- applepay
|
||||
- googlepay
|
||||
- samsungpay
|
9
spec/definitions/CryptoCurrency.yaml
Normal file
9
spec/definitions/CryptoCurrency.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
description: Криптовалюта
|
||||
type: string
|
||||
enum:
|
||||
- Bitcoin
|
||||
- Litecoin
|
||||
- BitcoinCash
|
||||
- Ripple
|
||||
- Ethereum
|
||||
- Zcash
|
17
spec/definitions/CryptoWallet.yaml
Normal file
17
spec/definitions/CryptoWallet.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
description: Данные криптовалютного кошелька
|
||||
allOf:
|
||||
- $ref: '#/definitions/DestinationResource'
|
||||
- type: object
|
||||
required:
|
||||
- cryptoWalletId
|
||||
- currency
|
||||
properties:
|
||||
cryptoWalletId:
|
||||
description: Идентификатор (он же адрес) криптовалютного кошелька
|
||||
type: string
|
||||
minLength: 16
|
||||
maxLength: 256
|
||||
example: zu3TcwGI71Bpaaw2XkLWZXlhMdn4zpVzMQ
|
||||
currency:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/CryptoCurrency'
|
6
spec/definitions/CurrencyID.yaml
Normal file
6
spec/definitions/CurrencyID.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
description: |
|
||||
Валюта, символьный код согласно [ISO
|
||||
4217](http://www.iso.org/iso/home/standards/currency_codes.htm).
|
||||
type: string
|
||||
pattern: '^[A-Z]{3}$'
|
||||
example: RUB
|
35
spec/definitions/Destination.yaml
Normal file
35
spec/definitions/Destination.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
description: Данные приемника денежных средств
|
||||
type: object
|
||||
required:
|
||||
- name
|
||||
- identity
|
||||
- currency
|
||||
- resource
|
||||
properties:
|
||||
id:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/DestinationID'
|
||||
- readOnly: true
|
||||
name:
|
||||
description: |
|
||||
Человекочитаемое название приёмника средств, по которому его легко узнать
|
||||
type: string
|
||||
example: Squarey plastic thingy
|
||||
identity:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/IdentityID'
|
||||
currency:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/CurrencyID'
|
||||
resource:
|
||||
$ref: '#/definitions/DestinationResource'
|
||||
metadata:
|
||||
description: |
|
||||
Произвольный, специфичный для клиента API и непрозрачный для системы набор данных, ассоциированных с
|
||||
данным приёмником
|
||||
type: object
|
||||
example:
|
||||
color_hint: olive-green
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
13
spec/definitions/DestinationAuthorized.yaml
Normal file
13
spec/definitions/DestinationAuthorized.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
description: Смена статуса приемника на авторизованный
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- destinationID
|
||||
properties:
|
||||
destinationID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/DestinationID'
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
9
spec/definitions/DestinationCreated.yaml
Normal file
9
spec/definitions/DestinationCreated.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
description: Событие создания приемника денежных средств
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- destination
|
||||
properties:
|
||||
destination:
|
||||
$ref: '#/definitions/Destination'
|
3
spec/definitions/DestinationID.yaml
Normal file
3
spec/definitions/DestinationID.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Идентификатор места назначения денежных средств
|
||||
type: string
|
||||
example: "10ASF74D98"
|
3
spec/definitions/DestinationName.yaml
Normal file
3
spec/definitions/DestinationName.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Человекочитаемое название места назначения, по которому его легко узнать
|
||||
type: string
|
||||
example: "Worldwide PHP Awareness Initiative"
|
14
spec/definitions/DestinationResource.yaml
Normal file
14
spec/definitions/DestinationResource.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
description: Ресурс приёмника денежных средств, используемый для осуществления выводов
|
||||
type: object
|
||||
discriminator: type
|
||||
required:
|
||||
- type
|
||||
properties:
|
||||
type:
|
||||
description: |
|
||||
Тип ресурса приёмника средств.
|
||||
type: string
|
||||
enum:
|
||||
- BankCard
|
||||
- CryptoWallet
|
||||
- DigitalWallet
|
13
spec/definitions/DestinationUnauthorized.yaml
Normal file
13
spec/definitions/DestinationUnauthorized.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
description: Смена статуса приемника на не авторизованный
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- destinationID
|
||||
properties:
|
||||
destinationID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/DestinationID'
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
21
spec/definitions/DigitalWallet.yaml
Normal file
21
spec/definitions/DigitalWallet.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
description: Данные криптовалютного кошелька
|
||||
allOf:
|
||||
- $ref: '#/definitions/DestinationResource'
|
||||
- type: object
|
||||
required:
|
||||
- digitalWalletId
|
||||
- digitalWalletProvider
|
||||
properties:
|
||||
digitalWalletId:
|
||||
description: Идентификатор
|
||||
type: string
|
||||
minLength: 16
|
||||
maxLength: 256
|
||||
example: zu3TcwGI71Bpaaw2XkLWZXlhMdn4zpVzMQ
|
||||
digitalWalletProvider:
|
||||
description: |
|
||||
Идентификатор провайдера
|
||||
type: string
|
||||
enum:
|
||||
- webmoney
|
||||
|
31
spec/definitions/Event.yaml
Normal file
31
spec/definitions/Event.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
description: Данные события
|
||||
type: object
|
||||
discriminator: eventType
|
||||
required:
|
||||
- occuredAt
|
||||
- topic
|
||||
- eventType
|
||||
properties:
|
||||
eventID:
|
||||
description: Идентификатор события в системе
|
||||
type: string
|
||||
occuredAt:
|
||||
description: Дата и время возникновения события
|
||||
type: string
|
||||
format: date-time
|
||||
topic:
|
||||
description: Предмет оповещения
|
||||
type: string
|
||||
enum:
|
||||
- WithdrawalTopic
|
||||
- DestinationTopic
|
||||
eventType:
|
||||
type: string
|
||||
description: Тип произошедшего с предметом оповещения события
|
||||
enum:
|
||||
- WithdrawalStarted
|
||||
- WithdrawalSucceeded
|
||||
- WithdrawalFailed
|
||||
- DestinationCreated
|
||||
- DestinationAuthorized
|
||||
- DestinationUnauthorized
|
6
spec/definitions/ExternalID.yaml
Normal file
6
spec/definitions/ExternalID.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
description: |
|
||||
Уникальный идентификатор сущности на вашей стороне.
|
||||
|
||||
При указании будет использован для того, чтобы гарантировать идемпотентную обработку операции.
|
||||
type: string
|
||||
example: "10036274"
|
3
spec/definitions/IdentityID.yaml
Normal file
3
spec/definitions/IdentityID.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Идентификатор личности владельца кошелька
|
||||
type: string
|
||||
example: tZ0jUmlsV0
|
3
spec/definitions/WalletID.yaml
Normal file
3
spec/definitions/WalletID.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Идентификатор кошелька
|
||||
type: string
|
||||
example: "10068321"
|
31
spec/definitions/Withdrawal.yaml
Normal file
31
spec/definitions/Withdrawal.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
description: Данные вывода денежных средств
|
||||
type: object
|
||||
required:
|
||||
- wallet
|
||||
- destination
|
||||
- body
|
||||
properties:
|
||||
id:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/WithdrawalID'
|
||||
createdAt:
|
||||
description: Дата и время запуска вывода
|
||||
type: string
|
||||
format: date-time
|
||||
destination:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/DestinationID'
|
||||
body:
|
||||
x-rebillyMerge:
|
||||
- description: Объём средств, которые необходимо вывести
|
||||
- $ref: '#/definitions/Asset'
|
||||
metadata:
|
||||
description: |
|
||||
Произвольный, специфичный для клиента API и непрозрачный для системы набор данных, ассоциированных с
|
||||
данным выводом
|
||||
wallet:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/WalletID'
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
13
spec/definitions/WithdrawalFailed.yaml
Normal file
13
spec/definitions/WithdrawalFailed.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
description: Событие о неуспешном осуществлении вывода средств
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- withdrawalID
|
||||
properties:
|
||||
withdrawalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/WithdrawalID'
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
3
spec/definitions/WithdrawalID.yaml
Normal file
3
spec/definitions/WithdrawalID.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
description: Идентификатор вывода денежных средств
|
||||
type: string
|
||||
example: tZ0jUmlsV0
|
9
spec/definitions/WithdrawalStarted.yaml
Normal file
9
spec/definitions/WithdrawalStarted.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
description: Событие о начале осуществления вывода средств
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- withdrawal
|
||||
properties:
|
||||
withdrawal:
|
||||
$ref: '#/definitions/Withdrawal'
|
13
spec/definitions/WithdrawalSucceeded.yaml
Normal file
13
spec/definitions/WithdrawalSucceeded.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
description: Событие об успешном осуществлении вывода средств
|
||||
allOf:
|
||||
- $ref: '#/definitions/Event'
|
||||
- type: object
|
||||
required:
|
||||
- withdrawalID
|
||||
properties:
|
||||
withdrawalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/WithdrawalID'
|
||||
externalID:
|
||||
x-rebillyMerge:
|
||||
- $ref: '#/definitions/ExternalID'
|
16
spec/paths/webhook-url.yaml
Normal file
16
spec/paths/webhook-url.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
post:
|
||||
tags:
|
||||
- Event Notifications
|
||||
summary: Оповестить о событии
|
||||
operationId: notifyWebhookEvent
|
||||
parameters:
|
||||
- $ref: '#/parameters/signature'
|
||||
- in: body
|
||||
name: event
|
||||
description: Данные произошедшего в системе события
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/Event'
|
||||
responses:
|
||||
'200':
|
||||
description: Оповещение обработано
|
96
spec/swagger.yaml
Normal file
96
spec/swagger.yaml
Normal file
@ -0,0 +1,96 @@
|
||||
swagger: '2.0'
|
||||
info:
|
||||
version: '0.1.0'
|
||||
title: Vality Wallets · Webhook Events API
|
||||
termsOfService: 'https://vality.dev/'
|
||||
description: |
|
||||
|
||||
## Wallet Webhook Events API
|
||||
|
||||
Данная спецификация определяет протокол доставки оповещений о возникновении
|
||||
новых событий по кошелькам в рамках вашей организации, которые система доставляет в
|
||||
виде HTTP-запросов на URL-адреса созданных вами webhook'ов. Обработчики для
|
||||
подобного рода запросов необходимо реализовать на стороне вашего серверного
|
||||
кода согласно данной спецификации.
|
||||
|
||||
Webhook — это подписка на определенный тип события либо их группу,
|
||||
касающихся различных объектов в рамках вашей организации. Для управления
|
||||
webhook'ами используются методы API, описанные в спецификации
|
||||
[Vality Webhook Management API](https://github.com/valitydev/swag-wallets).
|
||||
Когда наступает одно из событий в рамках определенного кошелька (например,
|
||||
изменение статуса кошелька), система выбирает
|
||||
webhook, подходящий под этот тип события, и отправляет HTTP-запрос,
|
||||
содержащий сообщение в формате JSON на указанный в этом webhook'е URL. Если
|
||||
вы создали несколько webhook'ов, подходящих под этот тип события, то событие
|
||||
доставляется одновременно на все заданные в них URL в неопределённом
|
||||
порядке.
|
||||
|
||||
## Стратегия доставки
|
||||
|
||||
Система гарантирует порядок доставки событий в рамках определенного предмета оповещения
|
||||
(кошелек, пополнение, выплата и т.п.). Система поддерживает очередь сообщений для каждого
|
||||
предмета оповещения, чтобы соблюсти очередность и гарантированную доставку.
|
||||
|
||||
Запрос на доставку считается успешным только при получении ответа со
|
||||
статусом `200`. Система будет ожидать успешного ответа на отправленный
|
||||
запрос в течение 10 секунд. В случае ответа любым другим статусом или по
|
||||
истечении указанного времени, отведённого на обработку оповещения, система
|
||||
будет пытаться повторно доставить оповещения до получения успешного ответа,
|
||||
либо до принятия решения о невозможности доставить информацию. Попытки
|
||||
доставки будут производиться со следующими временными интервалами между
|
||||
запросами:
|
||||
|
||||
- 30 секунд,
|
||||
- 5 минут,
|
||||
- 15 минут,
|
||||
- 1 час.
|
||||
- каждый час в течение суток (24 часа)
|
||||
|
||||
Если последняя попытка доставить оповещение оканчивается неудачей, все события, которые
|
||||
накопились в очереди этого кошелька, отбрасываются.
|
||||
|
||||
## Авторизация полученных сообщений
|
||||
|
||||
Система подтверждает подлинность оповещений, подписывая сообщения
|
||||
приватным ключом, уникальным для каждого webhook'а, парный публичный ключ к
|
||||
которому содержится в данных этого webhook'а. Подпись передается в
|
||||
HTTP-заголовке `Content-Signature`. В заголовке в виде различных атрибутов
|
||||
содержится информация об использованном при формировании подписи алгоритме и
|
||||
значение подписи в формате
|
||||
[URL-safe base-64](https://tools.ietf.org/html/rfc4648).
|
||||
|
||||
```
|
||||
Content-Signature: alg=RS256; digest=zFuf7bRH4RHwyktaqHQwmX5rn3LfSb4dKo...
|
||||
```
|
||||
|
||||
На данный момент возможно использование единственного алоритма формирования
|
||||
подписи.
|
||||
|
||||
### [RS256](https://tools.ietf.org/html/rfc7518#section-3.3)
|
||||
|
||||
Подпись формируется согласно алгоритму
|
||||
[RSASSA-PKCS1-v1_5](https://tools.ietf.org/html/rfc3447#section-8.2), на
|
||||
вход которому подаётся результат вычисления хэша сообщения по алгоритму
|
||||
[SHA-256](https://tools.ietf.org/html/rfc6234).
|
||||
|
||||
Набор атрибутов заголовка и список возможных алгоритмов формирования подписи
|
||||
в дальнейшем могут быть расширены.
|
||||
|
||||
schemes:
|
||||
- https
|
||||
consumes:
|
||||
- application/json; charset=utf-8
|
||||
produces:
|
||||
- application/json; charset=utf-8
|
||||
parameters:
|
||||
signature:
|
||||
name: Content-Signature
|
||||
in: header
|
||||
description: >
|
||||
Подпись сообщения, сформированная согласно указанным выше правилам
|
||||
required: true
|
||||
type: string
|
||||
tags:
|
||||
- name: Event Notifications
|
||||
x-displayName: Оповещения
|
||||
description: Доставка оповещений о событиях системы.
|
35
web/index.html
Normal file
35
web/index.html
Normal file
@ -0,0 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Vality Wallets · Webhook Events API</title>
|
||||
<!-- Needed for adaptive design -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js">
|
||||
</script>
|
||||
<!-- ReDoc doesn't change outer page styles -->
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id='redoc'></div>
|
||||
<script type="text/javascript">
|
||||
Redoc.init(
|
||||
"./swagger.json",
|
||||
{
|
||||
theme: {
|
||||
breakpoints: {
|
||||
// 3-panel view fix
|
||||
medium: '75rem'
|
||||
}
|
||||
}
|
||||
},
|
||||
document.getElementById('redoc')
|
||||
);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user