Compare commits

..

4 Commits

Author SHA1 Message Date
Ricardo Ambrogi
a3ebb01aee change types ext 2020-01-15 16:23:45 +01:00
Ricardo Ambrogi
e5d4d72098 fix tests type 2020-01-15 15:31:37 +01:00
Ricardo Ambrogi
2654f5b20a change tsconfig 2020-01-15 15:20:18 +01:00
Ricardo Ambrogi
605e364082 Bundle type definitions with package 2020-01-15 12:51:57 +00:00
1344 changed files with 34361 additions and 108106 deletions

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
const path = require('path');
module.exports = {
@@ -37,21 +18,12 @@ module.exports = {
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
rules: {
quotes: ["error", "double"],
semi: ["error", "always"],
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true,
"types": {
"{}": false
}
}
]
semi: ["error", "always"]
},
overrides: [
{

2
.github/CODEOWNERS vendored
View File

@@ -1 +1 @@
* @Adyen/javascript
* @KadoBOT @msilvagarcia @cyattilakiss @rkewlani @Aleffio @rikterbeek

View File

@@ -3,7 +3,7 @@ name: Bug report
about: Create a report to help us improve
title: '[BUG]'
labels: 'bug'
assignees: ''
assignees: 'KadoBOT'
---

View File

@@ -3,7 +3,7 @@ name: Feature request
about: Suggest an idea for this project
title: '[FEATURE]'
labels: 'feature'
assignees: ''
assignees: 'KadoBOT'
---

View File

@@ -1,7 +0,0 @@
**Description**
<!-- Please provide a description of the changes proposed in the Pull Request -->
**Tested scenarios**
<!-- Description of tested scenarios -->
**Fixed issue**: <!-- #-prefixed issue number -->

18
.github/stale.yml vendored
View File

@@ -1,18 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 60
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Label to use when marking an issue as stale
# Issues with these labels will never be considered stale
exemptLabels:
- Validating request
- Bug report
- Bug
- Enhancement
- feature
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.

View File

@@ -1,46 +0,0 @@
name: "Code scanning - action"
on:
push:
pull_request:
schedule:
- cron: '0 21 * * 4'
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2

View File

@@ -1,50 +0,0 @@
on: ["pull_request"]
name: Coveralls
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Use Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x
- name: npm install, npm test:coverage
run: |
npm install
npm run test:coverage
env:
CI: true
ADYEN_API_KEY: ${{ secrets.ADYEN_API_KEY }}
ADYEN_MERCHANT: ${{ secrets.ADYEN_MERCHANT }}
ADYEN_PASSWORD: ${{ secrets.ADYEN_PASSWORD }}
ADYEN_REVIEWPAYOUT_APIKEY: ${{ secrets.ADYEN_REVIEWPAYOUT_APIKEY }}
ADYEN_REVIEWPAYOUT_PASSWORD: ${{ secrets.ADYENREVIEWPAYOUT_PASSWORD }}
ADYEN_REVIEWPAYOUT_USER: ${{ secrets.ADYENREVIEWPAYOUT_USER }}
ADYEN_STOREPAYOUT_APIKEY: ${{ secrets.ADYEN_STOREPAYOUT_APIKEY }}
ADYEN_STOREPAYOUT_PASSWORD: ${{ secrets.ADYEN_STOREPAYOUT_PASSWORD }}
ADYEN_STOREPAYOUT_USER: ${{ secrets.ADYEN_STOREPAYOUT_USER }}
ADYEN_USER: ${{ secrets.ADYEN_USER }}
ADYEN_MARKETPLACE_USER: ${{ secrets.ADYEN_MARKETPLACE_USER }}
ADYEN_MARKETPLACE_PASSWORD: ${{ secrets.ADYEN_MARKETPLACE_PASSWORD }}
ADYEN_TERMINAL_APIKEY: ${{ secrets.ADYEN_TERMINAL_APIKEY }}
ADYEN_TERMINAL_POIID: ${{ secrets.ADYEN_TERMINAL_POIID }}
ADYEN_TERMINAL_MERCHANT: ${{ secrets.ADYEN_TERMINAL_MERCHANT }}
- name: Coveralls Parallel
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./coverage/lcov.info # optional (default value)
- name: Coveralls Finished
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,30 +0,0 @@
name: Node.js Models
on: [ workflow_dispatch ]
jobs:
generate:
runs-on: ubuntu-latest
name: Generate Models
steps:
- uses: actions/checkout@v3
- run: make models
- name: Set PR variables
id: vars
run: |
cd build/spec
echo ::set-output name=pr_title::"Update models"
echo ::set-output name=pr_body::"OpenAPI spec or templates produced new models on $(date +%d-%m-%Y) \
by [commit](https://github.com/Adyen/adyen-openapi/commit/$(git rev-parse HEAD))."
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
with:
token: ${{ secrets.ADYEN_AUTOMATION_BOT_ACCESS_TOKEN }}
committer: ${{ secrets.ADYEN_AUTOMATION_BOT_EMAIL }}
author: ${{ secrets.ADYEN_AUTOMATION_BOT_EMAIL }}
base: develop
branch: automation/models
title: ${{ steps.vars.outputs.pr_title }}
body: ${{ steps.vars.outputs.pr_body }}
add-paths: |
src/typings

View File

@@ -1,42 +0,0 @@
name: Node.js CI
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- name: npm install, lint and test
run: |
npm install
npm run lint:fix
npm run lint
npm test
env:
CI: true
ADYEN_API_KEY: ${{ secrets.ADYEN_API_KEY }}
ADYEN_MERCHANT: ${{ secrets.ADYEN_MERCHANT }}
ADYEN_PASSWORD: ${{ secrets.ADYEN_PASSWORD }}
ADYEN_REVIEWPAYOUT_APIKEY: ${{ secrets.ADYEN_REVIEWPAYOUT_APIKEY }}
ADYEN_REVIEWPAYOUT_PASSWORD: ${{ secrets.ADYENREVIEWPAYOUT_PASSWORD }}
ADYEN_REVIEWPAYOUT_USER: ${{ secrets.ADYENREVIEWPAYOUT_USER }}
ADYEN_STOREPAYOUT_APIKEY: ${{ secrets.ADYEN_STOREPAYOUT_APIKEY }}
ADYEN_STOREPAYOUT_PASSWORD: ${{ secrets.ADYEN_STOREPAYOUT_PASSWORD }}
ADYEN_STOREPAYOUT_USER: ${{ secrets.ADYEN_STOREPAYOUT_USER }}
ADYEN_USER: ${{ secrets.ADYEN_USER }}
ADYEN_MARKETPLACE_USER: ${{ secrets.ADYEN_MARKETPLACE_USER }}
ADYEN_MARKETPLACE_PASSWORD: ${{ secrets.ADYEN_MARKETPLACE_PASSWORD }}
ADYEN_TERMINAL_APIKEY: ${{ secrets.ADYEN_TERMINAL_APIKEY }}
ADYEN_TERMINAL_POIID: ${{ secrets.ADYEN_TERMINAL_POIID }}
ADYEN_TERMINAL_MERCHANT: ${{ secrets.ADYEN_TERMINAL_MERCHANT }}

View File

@@ -1,24 +0,0 @@
name: Node.js Package
on:
workflow_dispatch:
release:
types: [published]
jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 14
registry-url: https://registry.npmjs.org/
- run: |
npm install
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > .npmrc
npm run build
npm publish
env:
GITHUB_TOKEN: ${{ secrets.USER_GITHUB_TOKEN }}
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}

View File

@@ -1,21 +0,0 @@
name: "Sonarcloud Analysis"
on: ["pull_request"]
jobs:
sonarcloud-analysis:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
# Disabling shallow clone to improve relevancy of SonarCloud reporting
fetch-depth: 0
- name: SonarCloud integration
uses: sonarsource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

4
.gitignore vendored
View File

@@ -11,6 +11,4 @@ node_modules
.ssh/
.viminfo
coverage/
.env
lib/
build/
dist/

View File

@@ -1,16 +1,10 @@
src/
.babelrc
.eslintignore
.eslintrc.js
.eslintrc.json
.gitignore
.release-it.json
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Makefile
config.ts
renovate.json
.travis.yml
tsconfig.json
jest.config.js
tslint.json
.github
/**/__mocks__/
/**/__tests__/
webpack.config.js

View File

@@ -1,20 +1,12 @@
{
"git": {
"tagName": "v${version}",
"changelog": "npx auto-changelog --hide-credit --stdout --commit-limit false --unreleased-only -t keepachangelog",
"commitMessage": "Release ${version}",
"tag": true,
"requireCleanWorkingDir": false
"changelog": "npx auto-changelog --stdout --commit-limit false -u"
},
"github": {
"release": true,
"releaseName": "Adyen Node API Library v${version}"
"release": true
},
"hooks": {
"after:bump": [
"npm run build",
"npx auto-changelog -p"
],
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
"after:bump": "npx auto-changelog -p"
}
}

View File

@@ -1,13 +1,10 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright Contributors to the ODPi Egeria project.
# General settings
sonar.organization=adyen
sonar.projectKey=Adyen_adyen-node-api-library
# Path to sources
#sonar.sources=.
sonar.exclusions=src/__mocks__/**/* , src/typings/**/* , src/__tests__/**/*
sonar.exclusions=src/__mocks__/*
sonar.exclusions=src/typings/*
#sonar.inclusions=
# Path to tests

25
.travis.yml Normal file
View File

@@ -0,0 +1,25 @@
language: node_js
node_js:
- "8"
- stable
cache: yarn
script:
- yarn run lint:fix
- yarn run lint
- yarn run test
jobs:
include:
- stage: npm release
if: tag IS present
node_js: stable
script: yarn run build
deploy:
provider: npm
email: "$NPM_EMAIL"
api_key: "$NPM_TOKEN"
skip_cleanup: true
on:
tags: true
- stage: Produce Coverage
node_js: stable
script: jest --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020 Adyen
Copyright (c) 2019 Adyen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,74 +0,0 @@
generator:=typescript-node
openapi-generator-version:=5.4.0
openapi-generator-url:=https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/$(openapi-generator-version)/openapi-generator-cli-$(openapi-generator-version).jar
openapi-generator-jar:=build/openapi-generator-cli.jar
openapi-generator-cli:=java -jar $(openapi-generator-jar)
services:=balancePlatform binlookup checkout dataProtection legalEntityManagement management payments payouts platformsAccount platformsFund platformsHostedOnboardingPage platformsNotificationConfiguration recurring storedValue terminalManagement transfer
# Generate models (for each service)
models: $(services)
binlookup: spec=BinLookupService-v52
checkout: spec=CheckoutService-v69
dataProtection: spec=DataProtectionService-v1
storedValue: spec=StoredValueService-v46
terminalManagement: spec=TfmAPIService-v1
payments: spec=PaymentService-v68
recurring: spec=RecurringService-v68
payouts: spec=PayoutService-v68
management: spec=ManagementService-v1
managementapi: spec=ManagementService-v1
managementapi: service=management
legalEntityManagement: spec=LegalEntityService-v2
balancePlatform: spec=BalancePlatformService-v2
platformsAccount: spec=AccountService-v6
platformsFund: spec=FundService-v6
platformsNotificationConfiguration: spec=NotificationConfigurationService-v6
platformsHostedOnboardingPage: spec=HopService-v6
transfer: spec=TransferService-v3
$(services): build/spec $(openapi-generator-jar)
rm -rf src/typings/$@ build/model
$(openapi-generator-cli) generate \
-i build/spec/json/$(spec).json \
-g $(generator) \
-t templates/typescript \
-o build \
--global-property models,supportingFiles \
--additional-properties=serviceName=$@
mv build/model src/typings/$@
# Service
managementapi: build/spec $(openapi-generator-jar)
$(openapi-generator-cli) generate \
-i build/spec/json/$(spec).json \
-g $(generator) \
-t templates/typescript \
-o build \
--api-package $(service) \
--model-package typings/$(service) \
--global-property apis \
--additional-properties=serviceName=$(service)
cp build/$(service)/* src/services/$(service)
sed -i.bak '/RestServiceError/d' src/services/$(service)/*
rm src/services/$(service)/*.bak
# Checkout spec (and patch version)
build/spec:
git clone https://github.com/Adyen/adyen-openapi.git build/spec
perl -i -pe's/"openapi" : "3.[0-9].[0-9]"/"openapi" : "3.0.0"/' build/spec/json/*.json
# Extract templates (copy them for modifications)
templates: $(openapi-generator-jar)
$(openapi-generator-cli) author template -g $(generator) -o build/templates/typescript
# Download the generator
$(openapi-generator-jar):
wget --quiet -o /dev/null $(openapi-generator-url) -O $(openapi-generator-jar)
# Discard generated artifacts and changed models
clean:
git checkout src/typings src/services/management
git clean -f -d src/typings src/services/management
.PHONY: templates models $(services)

162
README.md
View File

@@ -1,47 +1,28 @@
![Node js](https://user-images.githubusercontent.com/62436079/207373079-9cf9377f-f530-4b02-a515-9b64ef7b06e7.png)
# Adyen Node.js API Library
![Node.js CI](https://github.com/Adyen/adyen-node-api-library/workflows/Node.js%20CI/badge.svg)
[![Coverage Status](https://coveralls.io/repos/github/Adyen/adyen-node-api-library/badge.svg?branch=main)](https://coveralls.io/github/Adyen/adyen-node-api-library?branch=main)
[![Build Status](https://travis-ci.org/Adyen/adyen-node-api-library.svg?branch=master)](https://travis-ci.org/Adyen/adyen-node-api-library)
[![Coverage Status](https://coveralls.io/repos/github/Adyen/adyen-node-api-library/badge.svg?branch=master)](https://coveralls.io/github/Adyen/adyen-node-api-library?branch=master)
[![Downloads](https://img.shields.io/npm/dm/@adyen/api-library.svg)](https://www.npmjs.com/package/@adyen/api-library)
![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/@adyen/api-library.svg)
[![Version](https://img.shields.io/npm/v/@adyen/api-library.svg)](https://www.npmjs.com/package/@adyen/api-library)
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=Adyen_adyen-node-api-library&metric=alert_status)](https://sonarcloud.io/dashboard?id=Adyen_adyen-node-api-library)
This is the officially supported NodeJS library for using Adyen's APIs.
The Adyen API Library for NodeJS enables you to work with Adyen APIs.
## Supported API versions
## Integration
The Library supports all APIs under the following services:
| API | Description | Service Name | Supported version |
| --- | ----------- | ------------ | ----------------- |
|[BIN lookup API](https://docs.adyen.com/api-explorer/#/BinLookup/v52/overview) | The BIN Lookup API provides endpoints for retrieving information based on a given BIN. | BinLookup | **v52** |
| [Checkout API](https://docs.adyen.com/api-explorer/#/CheckoutService/v69/overview)| Our latest integration for accepting online payments. | CheckoutAPI | **v69** |
| [Configuration API](https://docs.adyen.com/api-explorer/#/balanceplatform/v2/overview)| The Configuration API enables you to create a platform where you can onboard your users as account holders and create balance accounts, cards, and business accounts. | BalancePlatform | **v2** |
| [DataProtection API](https://docs.adyen.com/development-resources/data-protection-api) | Adyen Data Protection API provides a way for you to process [Subject Erasure Requests](https://gdpr-info.eu/art-17-gdpr/) as mandated in GDPR. Use our API to submit a request to delete shopper's data, including payment details and other related information (for example, delivery address or shopper email) | DataProtection | **v1** |
| [Legal Entity Management API](https://docs.adyen.com/api-explorer/#/legalentity/v2/overview)| Manage legal entities that contain information required for verification. | LegalEntityManagement | **v2** |
| [Local/Cloud-based Terminal API](https://docs.adyen.com/point-of-sale/terminal-api-reference)| Our point-of-sale integration. | TerminalLocalAPI or TerminalCloudAPI | - |
| [Management API](https://docs.adyen.com/api-explorer/#/ManagementService/v1/overview)| Configure and manage your Adyen company and merchant accounts, stores, and payment terminals. | Management | **v1** |
| [Payments API](https://docs.adyen.com/api-explorer/#/Payment/v68/overview)| Our classic integration for online payments. | ClassicIntegrationAPI | **v68** |
| [Payouts API](https://docs.adyen.com/api-explorer/#/Payout/v68/overview)| Endpoints for sending funds to your customers. | Payout | **v68** |
| [Platforms APIs](https://docs.adyen.com/platforms/api)| Set of APIs when using Adyen for Platforms. This API is used for the classic integration. | Platforms | - |
| [Account API](https://docs.adyen.com/api-explorer/#/Account/v6/overview) | *Platforms subclass* | Account | **v6** |
| [Fund API](https://docs.adyen.com/api-explorer/#/Fund/v6/overview) | *Platforms subclass* | Fund | **v6** |
| [Hosted onboarding API](https://docs.adyen.com/api-explorer/#/Hop/v6/overview)| *Platforms subclass* | HostedOnboardingPage | **v6** |
| [Notification Configuration API](https://docs.adyen.com/api-explorer/#/NotificationConfigurationService/v6/overview) | *Platforms subclass* | NotificationConfiguration | **v6** |
| [Platforms Notifications Webhooks](https://docs.adyen.com/api-explorer/#/NotificationService/v6/overview) || *Models only* | **v6** |
| [POS Terminal Management API](https://docs.adyen.com/api-explorer/#/postfmapi/v1/overview)| Endpoints for managing your point-of-sale payment terminals. | TerminalManagement | **v1** |
| [Recurring API](https://docs.adyen.com/api-explorer/#/Recurring/v68/overview)| Endpoints for managing saved payment details. | Recurring | **v68** |
| [Stored Value API](https://docs.adyen.com/payment-methods/gift-cards/stored-value-api) | Manage both online and point-of-sale gift cards and other stored-value cards. | StoredValue | **v46** |
| [Transfers API](https://docs.adyen.com/api-explorer/transfers/3/overview) | The Transfers API provides endpoints that can be used to get information about all your transactions, move funds within your balance platform or send funds from your balance platform to a transfer instrument. | Transfers | **v3** |
| [Webhooks](https://docs.adyen.com/api-explorer/Webhooks/1/overview) | Adyen uses webhooks to send notifications about payment status updates, newly available reports, and other events that can be subscribed to. For more information, refer to our [documentation](https://docs.adyen.com/development-resources/webhooks). | *Models only* | **v1** |
For more information, refer to our [documentation](https://docs.adyen.com/) or the [API Explorer](https://docs.adyen.com/api-explorer/).
* [x] checkout
* [x] checkout utility
* [x] payments
* [x] modifications
* [x] payouts
* [x] recurring
* [x] notifications
* [x] BIN lookup
## Prerequisites
- [Adyen test account](https://docs.adyen.com/get-started-with-adyen). To start using Adyen APIs, you will need a Merchant Account.
- [API key](https://docs.adyen.com/development-resources/api-credentials#generate-api-key). For testing, your API credential needs to have the [API PCI Payments role](https://docs.adyen.com/development-resources/api-credentials#roles).
- Node 12 or higher
## Requirements
* Node 8.1.1 or higher
## Installation
@@ -53,100 +34,12 @@ You can use NPM to add our library to your project
npm install --save @adyen/api-library
```
Alternatively, you can download the [release on GitHub](https://github.com/Adyen/adyen-node-api-library/releases).
## Documentation
* https://docs.adyen.com/developers/development-resources/libraries
* https://docs.adyen.com/developers/checkout/api-integration
## HTTP Client Configuration
## Using the library
### Client initialisation
#### General use with API key
Set up the client as a singleton resource; you can then use it to create service objects for the API calls that you make to Adyen:
```typescript
const { Client } = require('@adyen/api-library');
const client = new Client({apiKey: "YOUR_API_KEY", environment: "TEST"});
```
#### General use with API key for live environment
```typescript
const { Client } = require('@adyen/api-library');
const client = new Client({apiKey: "YOUR_API_KEY", environment: "LIVE"});
```
#### General use with basic auth
```typescript
const { Client } = require('@adyen/api-library');
const client = new Client({username: "YOUR_USERNAME", password: "YOUR_PASSWORD", environment: "TEST"});
```
### Consuming Services
Every API the library supports is represented by a service object. The name of the service matching the corresponding API is listed in the [Integrations](#supported-api-versions) section of this document.
```javascript
const { Client, CheckoutAPI } = require('@adyen/api-library');
const client = new Client({apiKey: "YOUR_API_KEY", environment: "TEST"});
const paymentRequest = {
amount: {
currency: "USD",
value: 1000 // value in minor units
},
reference: "Your order number",
paymentMethod: {
type: "scheme",
encryptedCardNumber: "test_4111111111111111",
encryptedExpiryMonth: "test_03",
encryptedExpiryYear: "test_2030",
encryptedSecurityCode: "test_737"
},
shopperReference: "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
storePaymentMethod: true,
shopperInteraction: "Ecommerce",
recurringProcessingModel: "CardOnFile",
returnUrl: "https://your-company.com/...",
merchantAccount: "YOUR_MERCHANT_ACCOUNT"
};
const checkoutAPI = new CheckoutAPI(client);
checkoutAPI.payments(paymentRequest)
.then( paymentResponse => console.log(paymentResponse.pspReference))
.catch(error => console.log(error));
```
Alternatively you can make use of the Types included in this library using Typescript, and/or use the async syntax:
```typescript
const { Client, CheckoutAPI } = require('@adyen/api-library');
const client = new Client({apiKey: "YOUR_API_KEY", environment: "TEST"});
import { Types } from '@adyen/api-library';
const doPaymentsRequest = async () => {
const paymentRequest : Types.checkout.PaymentRequest = {
amount: {
currency: "USD",
value: 1000 // value in minor units
},
reference: "Your order number",
paymentMethod: {
type: Types.checkout.CardDetails.TypeEnum.Scheme,
encryptedCardNumber: "test_4111111111111111",
encryptedExpiryMonth: "test_03",
encryptedExpiryYear: "test_2030",
encryptedSecurityCode: "test_737"
},
shopperReference: "YOUR_UNIQUE_SHOPPER_ID_IOfW3k9G2PvXFu2j",
storePaymentMethod: true,
shopperInteraction: Types.checkout.PaymentRequest.ShopperInteractionEnum.Ecommerce,
recurringProcessingModel: Types.checkout.PaymentRequest.RecurringProcessingModelEnum.CardOnFile,
returnUrl: "https://your-company.com/...",
merchantAccount: "YOUR_MERCHANT_ACCOUNT"
};
const checkoutAPI = new CheckoutAPI(client);
const paymentResponse : Types.checkout.PaymentResponse = await checkoutAPI.payments(paymentRequest);
console.log(paymentResponse.pspReference);
}
doPaymentsRequest();
```
### Custom HTTP Client Configuration
By default, NodeJS [https](https://nodejs.org/api/https.html) will be used to submit requests to the API. But you can change that by injecting your own HttpClient on your client instance. In the example below, we use `axios`:
```javascript
@@ -193,23 +86,18 @@ client.httpClient = httpClient;
...
```
### Example integration
For a closer look at how our NodeJS library works, clone our [example integration](https://github.com/adyen-examples/adyen-node-online-payments). This includes commented code, highlighting key features and concepts, and examples of API calls that can be made using the library.
## Support
## Contributing
If you have any problems, questions or suggestions, create an issue here or send your inquiry to support@adyen.com.
## Contributing
We strongly encourage you to join us in contributing to this repository so everyone can benefit from:
* New features and functionality
* Resolved bug fixes and issues
* Any general improvements
Read our [**contribution guidelines**](CONTRIBUTING.md) to find out how to create a pull request.
## Support
If you have a feature request, or spotted a bug or a technical problem, create a GitHub issue. For other questions, contact our [support team](https://www.adyen.help).
Read our [**contribution guidelines**](CONTRIBUTING.md) to find out how.
## Licence
This repository is available under the [MIT license](LICENSE).
## See also
* [example integration](https://github.com/adyen-examples/adyen-node-online-payments)
MIT license. For more information, see the LICENSE file.

25
babel.config.js Executable file
View File

@@ -0,0 +1,25 @@
module.exports = {
presets: [
"@babel/env",
[
"@babel/preset-typescript",
{
targets: {
node: "current"
}
}
]
],
plugins: [
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread"
],
env: {
test: {
plugins: [
"@babel/plugin-transform-runtime",
"@babel/plugin-transform-typescript"
]
}
}
}

View File

@@ -1,20 +0,0 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import "jest-ts-auto-mock"

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Adyen Node API Library
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
@@ -26,18 +28,14 @@ module.exports = {
coveragePathIgnorePatterns: [
"<rootDir>/src/typings"
],
setupFiles: ["<rootDir>config.ts", "dotenv/config"],
testMatch: [
"**/src/__tests__/**/*.spec.ts"
unmockedModulePathPatterns: [
"/dist"
],
roots: ['<rootDir>/src'],
transform: {
".ts": "ts-jest"
},
globals: {
"ts-jest": {
compiler: "ttypescript",
transformIgnorePatterns: ['^.+\\\\.js$']
}
},
testMatch: [
"**/__tests__/*.ts"
],
testPathIgnorePatterns : [
"/node_modules",
"/dist"
]
};

11806
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,12 @@
{
"name": "@adyen/api-library",
"version": "12.2.0",
"version": "2.2.1-rc.2",
"description": "The Adyen API Library for NodeJS enables you to work with Adyen APIs.",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"main": "dist/lib/src/index.js",
"types": "dist/lib/src/index.d.ts",
"module": "dist/lib-esm/src/index.js",
"engines": {
"node": ">=12"
"node": ">=8.1.1"
},
"repository": {
"type": "git",
@@ -24,41 +25,45 @@
},
"homepage": "https://github.com/Adyen/adyen-node-api-library#readme",
"scripts": {
"build": "tsc",
"clean": "rm -rf ./dist",
"build": "npm run clean && tsc && tsc -m es6 --outDir dist/lib-esm && webpack",
"lint": "eslint 'src/**/*.ts'",
"lint:fix": "eslint --fix 'src/**/*.ts'",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"release": "release-it"
"preversion": "npm test",
"version": "npm run build && git add -A dist",
"postversion": "git push && git push --tags && rm -rf build/temp",
"release": "release-it --no-npm.publish"
},
"author": "Ricardo Ambrogi",
"license": "MIT",
"devDependencies": {
"@types/jest": "27.5.2",
"@types/nock": "11.1.0",
"@typescript-eslint/eslint-plugin": "5.43.0",
"@typescript-eslint/parser": "5.45.0",
"acorn": "^8.0.1",
"coveralls": "3.1.1",
"dotenv": "^16.0.0",
"eslint": "8.28.0",
"jest": "^27.0.6",
"jest-ts-auto-mock": "^2.0.0",
"kind-of": "^6.0.3",
"minimist": ">=1.2.3",
"nock": "13.3.0",
"release-it": "15.5.0",
"ts-auto-mock": "^3.3.5",
"ts-jest": "^27.0.4",
"ts-loader": "9.4.2",
"ttypescript": "^1.5.10",
"typescript": "4.9.4"
"@babel/core": "7.8.3",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/plugin-proposal-object-rest-spread": "7.8.3",
"@babel/plugin-transform-runtime": "7.8.3",
"@babel/plugin-transform-typescript": "7.8.3",
"@babel/preset-env": "7.8.3",
"@babel/preset-typescript": "7.8.3",
"@babel/runtime": "7.8.3",
"@types/nock": "10.0.3",
"@typescript-eslint/eslint-plugin": "2.16.0",
"@typescript-eslint/parser": "2.16.0",
"babel-loader": "8.0.6",
"coveralls": "3.0.9",
"eslint": "6.8.0",
"jest": "24.9.0",
"nock": "11.7.2",
"release-it": "12.4.3",
"ts-jest": "24.3.0",
"ts-loader": "6.2.1",
"typescript": "3.7.4",
"webpack": "4.41.5",
"webpack-cli": "3.3.10"
},
"dependencies": {
"https-proxy-agent": "5.0.1"
},
"optionalDependencies": {
"@types/node": "14.18.36"
"@types/node": "13.1.7",
"@types/jest": "24.0.25",
"https-proxy-agent": "4.0.0"
}
}

View File

@@ -1,5 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:base"
]

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2021 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
@@ -27,116 +29,70 @@ import {
MessageType,
PaymentRequest,
PaymentTransaction,
ReversalReasonType,
ReversalRequest,
SaleData,
SaleToPOIRequest,
SaleToPoiRequest,
TerminalApiRequest,
TransactionIdentification
} from "../typings/terminal/models";
TransactionIdentification,
} from "../typings/terminal";
export const createClient = (apiKey = process.env.ADYEN_API_KEY): Client => {
export const createMockClientFromResponse = (): Client => {
const config: Config = new Config();
config.terminalApiCloudEndpoint = Client.TERMINAL_API_ENDPOINT_TEST;
config.terminalApiLocalEndpoint = "https://mocked_local_endpoint.com";
config.hmacKey = "DFB1EB5485895CFA84146406857104ABB4CBCABDC8AAF103A624C8F6A3EAAB00";
config.endpoint = Client.ENDPOINT_TEST;
config.checkoutEndpoint = Client.CHECKOUT_ENDPOINT_TEST;
config.marketPayEndpoint = Client.MARKETPAY_ENDPOINT_TEST;
config.apiKey = apiKey;
config.paymentEndpoint = Client.PAYMENT_API_ENDPOINT_TEST;
config.storedValueEndpoint = Client.STOREDVALUE_API_ENDPOINT_TEST;
config.terminalManagementEndpoint = Client.TERMINAL_MANAGEMENT_API_ENDPOINT_TEST;
config.managementEndpoint = Client.MANAGEMENT_API_ENDPOINT_TEST;
config.balancePlatformEndpoint = Client.BALANCE_PLATFORM_API_ENDPOINT_TEST;
config.legalEntityManagementEndpoint = Client.LEGAL_ENTITY_MANAGEMENT_API_ENDPOINT_TEST;
config.transfersEndpoint = Client.TRANSFERS_API_ENDPOINT_TEST;
config.dataProtectionEndpoint = Client.DATA_PROTECTION_API_ENDPOINT_TEST;
config.apiKey = "MOCKED_API_KEY";
return new Client({ config });
const client: Client = new Client({ config });
return client;
};
export const createBasicAuthClient = (): Client => {
return new Client({
username: process.env.ADYEN_USER!,
password: process.env.ADYEN_PASSWORD!,
environment: "TEST",
applicationName: "adyen-node-api-library"
});
};
const id = Math.floor(Math.random() * Math.floor(10000000)).toString();
const getMessageHeader = ({ messageCategory = MessageCategoryType.Payment }: { messageCategory?: MessageCategoryType } = {}): MessageHeader => ({
MessageCategory: messageCategory,
MessageClass: MessageClassType.Service,
MessageType: MessageType.Request,
POIID: process.env.ADYEN_TERMINAL_POIID!,
ProtocolVersion: "3.0",
SaleID: id,
ServiceID: id,
});
const timestamp = (): string => new Date().toISOString();
const transactionIdentification: TransactionIdentification = {
TimeStamp: timestamp(),
TransactionID: id,
};
const saleData: SaleData = {
SaleTransactionID: transactionIdentification,
SaleToAcquirerData: {
applicationInfo: {
merchantApplication: {
version: "1",
name: "test"
}
},
metadata: {
someMetaDataKey1: "YOUR_VALUE",
someMetaDataKey2: "YOUR_VALUE"
},
}
};
const amountsReq: AmountsReq = {
Currency: "EUR",
RequestedAmount: 1,
};
const paymentTransaction: PaymentTransaction = {
AmountsReq: amountsReq,
};
const paymentRequest: PaymentRequest = {
PaymentTransaction: paymentTransaction,
SaleData: saleData,
};
const getReversalRequest = (poiTransaction: TransactionIdentification): ReversalRequest => ({
OriginalPOITransaction: {
POITransactionID: {
TransactionID: poiTransaction.TransactionID,
TimeStamp: poiTransaction.TimeStamp
},
},
ReversalReason: ReversalReasonType.MerchantCancel,
SaleData: saleData
});
const getSaleToPOIRequest = (messageHeader: MessageHeader, request: Partial<SaleToPOIRequest>): SaleToPOIRequest => ({
MessageHeader: messageHeader,
...request
});
export const createTerminalAPIPaymentRequest = (): TerminalApiRequest => {
const messageHeader = getMessageHeader();
const saleToPOIRequest = getSaleToPOIRequest(messageHeader, { PaymentRequest: paymentRequest });
return { SaleToPOIRequest: saleToPOIRequest };
};
export const createTerminalAPIRefundRequest = (transactionIdentification: TransactionIdentification): TerminalApiRequest => {
const messageHeader = getMessageHeader({ messageCategory: MessageCategoryType.Reversal });
const saleToPOIRequest = getSaleToPOIRequest(messageHeader, { ReversalRequest: getReversalRequest(transactionIdentification) });
return { SaleToPOIRequest: saleToPOIRequest };
const messageHeader: MessageHeader = {
messageCategory: MessageCategoryType.Payment,
messageClass: MessageClassType.Service,
messageType: MessageType.Request,
poiid: "P400Plus-123456789",
protocolVersion: "3.0",
saleId: "001",
serviceId: "001",
};
const timestamp = new Date().toISOString();
const transactionIdentification: TransactionIdentification = {
timeStamp: timestamp,
transactionId: "001",
};
const saleData: SaleData = {
saleTransactionId: transactionIdentification,
};
const amountsReq: AmountsReq = {
currency: "EUR",
requestedAmount: 1,
};
const paymentTransaction: PaymentTransaction = {
amountsReq: amountsReq,
};
const paymentRequest: PaymentRequest = {
paymentTransaction: paymentTransaction,
saleData: saleData,
};
const saleToPOIRequest: SaleToPoiRequest = {
messageHeader: messageHeader,
paymentRequest: paymentRequest,
};
const terminalApiRequest: TerminalApiRequest = {
saleToPoiRequest: saleToPOIRequest,
};
return terminalApiRequest;
};

View File

@@ -1,26 +0,0 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const originKeysSuccess = JSON.stringify({
originKeys: {
"https://www.your-domain.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4xLmNvbQ.UEwIBmW9-c_uXo5wSEr2w8Hz8hVIpujXPHjpcEse3xI",
"https://www.your-domain2.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4yLmNvbQ.EP6eXBJKk0t7-QIUl6e_b1qMuMHGepxG_SlUqxAYrfY",
"https://www.your-domain3.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4zLmNvbQ.fUvflu-YIdZSsLEH8Qqmr7ksE4ag_NYiiMXK0s6aq_4",
},
});

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentMethodsSuccess = JSON.stringify({
paymentMethods: [

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentSessionError = {
statusCode: 422,

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const paymentMethodsError = {
errorCode: "901",
errorType: "security",

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentDetailsError = {
statusCode: 422,

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentDetailsSuccess = JSON.stringify({
pspReference: "8515232733321252",

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentsError = JSON.stringify({
statusCode: 422,

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentsResultError = JSON.stringify({
statusCode: 422,

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentsResultMultibancoSuccess = {
additionalData: {

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentsResultSuccess = JSON.stringify({
pspReference: "8535253563623704",

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const paymentsSuccess = JSON.stringify({
additionalData: {
@@ -29,7 +10,6 @@ export const paymentsSuccess = JSON.stringify({
alias: "H167852639363479",
cardPaymentMethod: "visa",
cardIssuingCountry: "NL",
"recurring.recurringDetailReference": "8415883203388055",
},
fraudResult: {
accountScore: 0,

View File

@@ -1,33 +0,0 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
/* tslint:disable */
export const sessionsSuccess = JSON.stringify({
"amount": {
"currency": "EUR",
"value": 100
},
"countryCode": "NL",
"expiresAt": "2021-10-08T17:28:56+02:00",
"id": "CS841C62BF399F968C",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"reference": "YOUR_PAYMENT_REFERENCE",
"returnUrl": "https://your-company.com/checkout?shopperOrder=12xy..",
"sessionData": "Ab02b4c0!BQABAgAeRei/Zyr+UYwMcTlHkeYjwn143zTmCmDmWwBg+gZr8us16qqoeVFon6NexiKmZLurm05iRiLagbIIS8BtFzvtX5myx4m0N1vBJWZRDZKHP3g4cyXjEnTnK0CmNsX0bDeojkHU4qChCkn1jIux/rSSp2IIBqe1SfbGVRC9bM17Nj90fJPBxp5MFMw7HKpuvlRNj8CncKPAyPhd4pY+O3GKTiFoZKpx/kVKO7PnILEC07q4rqEzVjSW2U5ADcnR+mJ8V0YVn8Yy4KqNLn68GKMHXe2+NRvidA/UC72F72dOtV1bqxRr/0G6bCW7iuxve+M0IYZ3apHbgS1vWcvUaOI7n1u02M6SWsZDcKgsaT0PoxQkUvdU3ViG7f7Xtac8pjcOxAzhtug/B6Qx/zaTUIWBRKQM5Ga9T7Vo9s9I1Kgv3zuQqeN9OiUhB1mvoxfSPkKYTVjYooj4CELNy9+xuU8/TI+XqK24FIiTacvcJ8Vt0RCSWcE47AG4qiKPBFcBMwpUfz78ud/gu4uBHtt/bh5vJu5GG462tr5W3a/5CeGDX37sqTnrUGom86daTll+kbKo3rC4CH8+K245XNIvIVXLUGrci52lzm09ptPEh/Aj8uBGHLA4Cc0ILAi3rxI5nNcurgbAZiZ7QA3iBEih4euVXBZmKRIfY2U0ijEQLBo8mBDuOjj4GNFT2XrRVs2rwhldAEp7ImtleSI6IkFGMEFBQTEwM0NBNTM3RUFFRDg3QzI0REQ1MzkwOUI4MEE3OEE5MjNFMzgyM0Q2OERBQ0M5NEI5RkY4MzA1REMifWHVSkL3b2GTohsmKmsBVvRtOiDyOWBpV+mylCFs/EQuj7PFJBVjaLoIq1Prk4hZFhBzEf7SsQYHzfTr+BKFH+6fblTW4ObszU3YwF6ehRDaLYxv4sPdVPdguWcuxIvzRenzPlGWu78z6cj1ROHNE3uREUgmVYf9ERbMm8OKJ/uqS1pMPvCYcHIJ0IrXbloQhKaSZdJNmsjGFbfBW8Tr29foxKH280TjbauaZydPWsEuEUIyeWYFBMoozW7de/6RLrDhnQEn/We/6EmsL86QzG+JSkBFloTFo2kdttqA9dfK0l7U3HjtEXmNBFy13DTr5tJcYMz+IcTwe0PqPCgUR+MZDOpAOFc1uHdccok7sttiV4K4xTKkpThiCgrAqklNoD7UcctS5c7RaNQxrwHM5orI0vkGG2hzDXKOUNw4068u"
});

View File

@@ -0,0 +1,7 @@
export const originKeysSuccess = JSON.stringify({
originKeys: {
"https://www.your-domain1.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4xLmNvbQ.UEwIBmW9-c_uXo5wSEr2w8Hz8hVIpujXPHjpcEse3xI",
"https://www.your-domain2.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4yLmNvbQ.EP6eXBJKk0t7-QIUl6e_b1qMuMHGepxG_SlUqxAYrfY",
"https://www.your-domain3.com": "pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4zLmNvbQ.fUvflu-YIdZSsLEH8Qqmr7ksE4ag_NYiiMXK0s6aq_4",
},
});

View File

@@ -1,233 +0,0 @@
export const businessLineInfo = {
"capability": "issueBankAccount",
"industryCode": "55",
"webData": [
{
"webAddress": "https://www.adyen.com"
}
],
"legalEntityId": "LE322KT223222D5FJ7THR293F",
"sourceOfFunds": {
"type": "business",
"adyenProcessedFunds": "false",
"description": "Funds from my flower shop business"
}
};
export const businessLineInfoUpdate = {
"capability": "string",
"industryCode": "string",
"legalEntityId": "string",
"salesChannels": ["string"],
"sourceOfFunds": {
"acquiringBusinessLineId": "string",
"adyenProcessedFunds": false,
"description": "string",
"type": "business"
},
"webData": [{ "webAddress": "string" }],
"webDataExemption": { "reason": "noOnlinePresence" }
};
export const document = {
"attachment": {
"content": "string",
"contentType": "string",
"filename": "string",
"pageName": "string",
"pageType": "string"
},
"attachments": [{
"content": "string",
"contentType": "string",
"filename": "string",
"pageName": "string",
"pageType": "string"
}],
"description": "string",
"expiryDate": "string",
"fileName": "string",
"id": "string",
"issuerCountry": "string",
"issuerState": "string",
"number": "string",
"owner": {
"id": "string",
"type": "string"
},
"type": "bankStatement"
};
export const onboardingLinkInfo = {
"locale": "cs-CZ",
"redirectUrl": "https://your.redirect-url.com",
"themeId": "123456789"
};
export const legalEntityInfo = {
"type": "individual",
"individual": {
"residentialAddress": {
"city": "San Francisco",
"country": "US",
"postalCode": "94107",
"street": "Brannan Street 274",
"stateOrProvince": "CA"
},
"phone": {
"countryCode": "US",
"number": "5551231234",
"type": "mobile"
},
"name": {
"firstName": "Simone",
"lastName": "Hopper"
},
"birthData": {
"dateOfBirth": "1981-12-01"
},
"email": "s.hopper@example.com"
}
};
export const genericEntityInfo = {
"entityAssociations": [{
"associatorId": "string",
"entityType": "string",
"jobTitle": "string",
"legalEntityId": "string",
"name": "string",
"type": "signatory"
}],
"individual": {
"birthData": { "dateOfBirth": "string" },
"email": "string",
"identificationData": {
"expiryDate": "string",
"issuerCountry": "string",
"issuerState": "string",
"nationalIdExempt": false,
"number": "string",
"type": "bankStatement"
},
"name": {
"firstName": "string",
"infix": "string",
"lastName": "string"
},
"nationality": "string",
"phone": {
"number": "string",
"type": "string"
},
"residentialAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"taxInformation": [{
"country": "string",
"number": "string",
"type": "string"
}],
"webData": { "webAddress": "string" }
},
"organization": {
"description": "string",
"doingBusinessAs": "string",
"email": "string",
"legalName": "string",
"phone": {
"number": "string",
"type": "string"
},
"principalPlaceOfBusiness": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registeredAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registrationNumber": "string",
"stockData": {
"marketIdentifier": "string",
"stockNumber": "string",
"tickerSymbol": "string"
},
"taxInformation": [{
"country": "string",
"number": "string",
"type": "string"
}],
"taxReportingClassification": {
"businessType": "other",
"financialInstitutionNumber": "string",
"mainSourceOfIncome": "businessOperation",
"type": "nonFinancialNonReportable"
},
"type": "associationIncorporated",
"vatAbsenceReason": "industryExemption",
"vatNumber": "string",
"webData": { "webAddress": "string" }
},
"soleProprietorship": {
"countryOfGoverningLaw": "string",
"doingBusinessAs": "string",
"name": "string",
"principalPlaceOfBusiness": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registeredAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registrationNumber": "string",
"vatAbsenceReason": "industryExemption",
"vatNumber": "string"
}
};
export const transferInstrumentInfo = {
"bankAccount": {
"accountNumber": "string",
"accountType": "string",
"bankBicSwift": "string",
"bankCity": "string",
"bankCode": "string",
"bankName": "string",
"branchCode": "string",
"checkCode": "string",
"countryCode": "string",
"currencyCode": "string",
"iban": "string"
},
"legalEntityId": "string",
"recurringDetail": {
"merchantAccount": "string",
"reference": "string",
"shopperReference": "string"
},
"type": "bankAccount"
};

View File

@@ -1,241 +0,0 @@
export const businessLine = {
"capability": "receivePayments",
"id": "123456789",
"industryCode": "123456789",
"legalEntityId": "123456789",
"salesChannels": ["string"],
"sourceOfFunds": {
"acquiringBusinessLineId": "string",
"adyenProcessedFunds": false,
"description": "string",
"type": "business"
},
"webData": [{ "webAddress": "string" }],
"webDataExemption": { "reason": "noOnlinePresence" }
};
export const document = {
"attachment": {
"content": "string",
"contentType": "string",
"filename": "string",
"pageName": "string",
"pageType": "string"
},
"attachments": [{
"content": "string",
"contentType": "string",
"filename": "string",
"pageName": "string",
"pageType": "string"
}],
"description": "string",
"expiryDate": "string",
"fileName": "string",
"id": "123456789",
"issuerCountry": "string",
"issuerState": "string",
"number": "string",
"owner": {
"id": "123456789",
"type": "passport"
},
"type": "driversLicense"
};
export const onboardingLink = { "url": "https://your.redirect-url.com" };
export const onboardingThemes = {
"next": "string",
"previous": "string",
"themes": [{
"createdAt": "2022-10-31T01:30:00.000Z",
"description": "string",
"id": "123456789",
"properties": { "sample": "string" },
"updatedAt": "2022-10-31T01:30:00.000Z"
}]
};
export const onboardingTheme = {
"createdAt": "string",
"description": "string",
"id": "123456789",
"properties": { "sample": "string" },
"updatedAt": "string"
};
export const legalEntity = {
"documentDetails": [{
"active": false,
"fileName": "string",
"id": "string"
}],
"documents": [{ "id": "string" }],
"entityAssociations": [{
"associatorId": "string",
"entityType": "string",
"jobTitle": "string",
"legalEntityId": "string",
"name": "string",
"type": "signatory"
}],
"id": "123456789",
"individual": {
"birthData": { "dateOfBirth": "string" },
"email": "string",
"identificationData": {
"expiryDate": "string",
"issuerCountry": "string",
"issuerState": "string",
"nationalIdExempt": false,
"number": "string",
"type": "bankStatement"
},
"name": {
"firstName": "string",
"infix": "string",
"lastName": "string"
},
"nationality": "string",
"phone": {
"number": "string",
"type": "string"
},
"residentialAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"taxInformation": [{
"country": "string",
"number": "string",
"type": "string"
}],
"webData": { "webAddress": "string" }
},
"organization": {
"description": "string",
"doingBusinessAs": "string",
"email": "string",
"legalName": "string",
"phone": {
"number": "string",
"type": "string"
},
"principalPlaceOfBusiness": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registeredAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registrationNumber": "string",
"stockData": {
"marketIdentifier": "string",
"stockNumber": "string",
"tickerSymbol": "string"
},
"taxInformation": [{
"country": "string",
"number": "string",
"type": "string"
}],
"taxReportingClassification": {
"businessType": "other",
"financialInstitutionNumber": "string",
"mainSourceOfIncome": "businessOperation",
"type": "nonFinancialNonReportable"
},
"type": "associationIncorporated",
"vatAbsenceReason": "industryExemption",
"vatNumber": "string",
"webData": { "webAddress": "string" }
},
"reference": "string",
"soleProprietorship": {
"countryOfGoverningLaw": "string",
"doingBusinessAs": "string",
"name": "string",
"principalPlaceOfBusiness": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registeredAddress": {
"city": "string",
"country": "string",
"postalCode": "string",
"stateOrProvince": "string",
"street": "string",
"street2": "string"
},
"registrationNumber": "string",
"vatAbsenceReason": "industryExemption",
"vatNumber": "string"
},
"transferInstruments": [{ "id": "string" }],
"type": "individual"
};
export const businessLines = {
"businessLines": [{
"capability": "receivePayments",
"id": "123456789",
"industryCode": "123456789",
"legalEntityId": "123456789",
"salesChannels": ["string"],
"sourceOfFunds": {
"acquiringBusinessLineId": "string",
"adyenProcessedFunds": false,
"description": "string",
"type": "business"
},
"webData": [{ "webAddress": "string" }],
"webDataExemption": { "reason": "noOnlinePresence" }
}]
};
export const transferInstrument = {
"bankAccount": {
"accountNumber": "string",
"accountType": "string",
"bankBicSwift": "string",
"bankCity": "string",
"bankCode": "string",
"bankName": "string",
"branchCode": "string",
"checkCode": "string",
"countryCode": "string",
"currencyCode": "string",
"iban": "string"
},
"documentDetails": [{
"active": false,
"fileName": "string",
"id": "string"
}],
"id": "123456789",
"legalEntityId": "123456789",
"recurringDetail": {
"merchantAccount": "string",
"reference": "string",
"shopperReference": "string"
},
"type": "bankAccount"
};

View File

@@ -1,225 +0,0 @@
export const createMerchantRequest = {
"companyId": "YOUR_COMPANY_ACCOUNT",
"legalEntityId": "YOUR_LEGAL_ENTITY_ID",
"businessLineId": "YOUR_BUSINESS_LINE_ID",
"description": "YOUR_DESCRIPTION",
"reference": "YOUR_OWN_REFERENCE"
};
export const allowedOrigin = {
"_links": { "self": { "href": "string" } },
"domain": "string",
"id": "string"
};
export const createMerchantApiCredentialRequest = {
"roles": [
"Checkout webservice role"
],
"allowedOrigins": [
"https://www.mystore.com"
]
};
export const updateMerchantApiCredentialRequest = {
"active": false,
"allowedOrigins": ["string"],
"description": "string",
"roles": ["string"]
};
export const paymentMethodSetupInfo = {
"type": "visa",
"currencies": [
"USD"
],
"countries": [
"US"
]
};
export const updatePaymentMethodInfo = {
"countries": ["string"],
"currencies": ["string"],
"enabled": false
};
export const payoutSettingsRequest = {
"enabled": false,
"enabledFromDate": "string",
"transferInstrumentId": "string"
};
export const updatePayoutSettingsRequest = { "enabled": false };
export const shippingLocation = {
"name": "YOUR_MERCHANT_ACCOUNT Barcelona depot",
"address": {
"companyName": "YOUR_COMPANY",
"streetAddress": "El quinto pino 42",
"postalCode": "08012",
"city": "Barcelona",
"stateOrProvince": "",
"country": "ES"
},
"contact": {
"firstName": "Rita",
"lastName": "Perengano",
"phoneNumber": "+34 93 1234567",
"email": "Rita.Perengano@company.com"
}
};
export const terminalOrderRequest = {
"shippingLocation": "S2-73536B20665526704F30792642212044452F714622375D477270",
"items": [
{
"id": "TBOX-V400m-684-EU",
"name": "V400m Package",
"quantity": 1
},
{
"id": "PART-287001-EU",
"name": "Bluetooth Charging Base - V400m",
"quantity": 2
},
{
"id": "PART-620222-EU",
"name": "Receipt Roll",
"quantity": 20
}
]
};
export const logo = {
"data": ""
};
export const terminalSettings = {
"wifiProfiles": {
"profiles": [
{
"authType": "wpa-eap",
"autoWifi": false,
"bssType": "infra",
"channel": 0,
"defaultProfile": true,
"eap": "peap",
"eapCaCert": {
"data": "MD1rKS05M2JqRVFNQ...RTtLH1tLWo=",
"name": "eap-peap-ca.pem"
},
"eapIdentity": "admin",
"eapIntermediateCert": {
"data": "PD3tUS1CRDdJTiGDR...EFoLS0tLQg=",
"name": "eap-peap-client.pem"
},
"eapPwd": "EAP_PEAP_PASSWORD",
"hiddenSsid": false,
"name": "Profile-eap-peap-1",
"ssid": "your-network",
"wsec": "ccmp"
},
{
"authType": "wpa-psk",
"autoWifi": false,
"bssType": "infra",
"channel": 0,
"defaultProfile": false,
"hiddenSsid": false,
"name": "Profile-guest-wifi",
"psk": "WIFI_PASSWORD",
"ssid": "your-network",
"wsec": "ccmp"
}
],
"settings": {
"band": "2.4GHz",
"roaming": true,
"timeout": 5
}
}
};
export const createMerchantUserRequest = {
"name": {
"firstName": "John",
"lastName": "Smith"
},
"username": "johnsmith",
"email": "john.smith@example.com",
"timeZoneCode": "Europe/Amsterdam",
"roles": [
"Merchant standard role"
],
"associatedMerchantAccounts": [
"YOUR_MERCHANT_ACCOUNT"
]
};
export const updateMerchantUserRequest = {
"accountGroups": ["string"],
"active": false,
"email": "string",
"name": {
"firstName": "string",
"lastName": "string"
},
"roles": ["string"],
"timeZoneCode": "string"
};
export const createMerchantWebhookRequest = {
"acceptsExpiredCertificate": false,
"acceptsSelfSignedCertificate": false,
"acceptsUntrustedRootCertificate": false,
"active": false,
"additionalSettings": {
"includeEventCodes": ["string"],
"properties": { "sample": false }
},
"communicationFormat": "HTTP",
"description": "string",
"networkType": "LOCAL",
"password": "string",
"populateSoapActionHeader": false,
"sslVersion": "HTTP",
"type": "string",
"url": "string",
"username": "string"
};
export const updateMerchantWebhookRequest = {
"acceptsExpiredCertificate": false,
"acceptsSelfSignedCertificate": false,
"acceptsUntrustedRootCertificate": false,
"active": false,
"additionalSettings": {
"includeEventCodes": ["string"],
"properties": { "sample": false }
},
"communicationFormat": "HTTP",
"description": "string",
"networkType": "LOCAL",
"password": "string",
"populateSoapActionHeader": false,
"sslVersion": "HTTP",
"url": "string",
"username": "string"
};
export const testWebhookRequest = {
"notification": {
"amount": {
"currency": "string",
"value": 0
},
"eventCode": "string",
"eventDate": "string",
"merchantReference": "string",
"paymentMethod": "string",
"reason": "string",
"success": false
},
"types": ["string"]
};

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,7 @@
"totalFraudScore": "10",
"hmacSignature": "OzDjCMZIsdtDqrZ+cl\/FWC+WdESrorctXTzAzW33dXI=",
"NAME2": " VALUE2 ",
"fraudCheck-6-ShopperIpUsage": "10",
"paymentLinkId": "ABCDEFG"
"fraudCheck-6-ShopperIpUsage": "10"
},
"amount": {
"currency": "EUR",

View File

@@ -22,4 +22,4 @@
}
}
]
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,3 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const disableSuccess = {
response: "[detail-successfully-disabled]",
};

View File

@@ -1,77 +1,52 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const listRecurringDetailsSuccess = {
"creationDate": "2017-03-01T11:53:11+01:00",
"details": [
creationDate: "2017-03-01T10:53:11.000",
details: [
{
"acquirer": "TestPmmAcquirer",
"acquirerAccount": "TestPmmAcquirerAccount",
"additionalData": {
"cardBin": "411111"
additionalData: {
cardBin: "411111",
},
"alias": "cardAlias",
"aliasType": "Default",
"card": {
"expiryMonth": "8",
"expiryYear": "2018",
"holderName": "Holder",
"number": "1111"
alias: "cardAlias",
aliasType: "Default",
card: {
expiryMonth: "8",
expiryYear: "2018",
holderName: "Holder",
number: "1111",
},
"contractTypes": [
"ONECLICK"
contractTypes: [
"ONECLICK",
],
"creationDate": "2017-03-07T09:43:33+01:00",
"firstPspReference": "8524888762135795",
"paymentMethodVariant": "visa",
"recurringDetailReference": "recurringReference",
"variant": "visa"
creationDate: "2017-03-01T10:53:11.000",
firstPspReference: "8524888762135795",
paymentMethodVariant: "visa",
recurringDetailReference: "recurringReference",
variant: "visa",
},
{
"acquirer": "PayPalSandbox",
"acquirerAccount": "TestPmmAcquirerAccount",
"billingAddress": {
"city": "City",
"country": "NL",
"houseNumberOrName": "1",
"postalCode": "2312aa",
"stateOrProvince": "NA",
"street": "Street"
billingAddress: {
city: "City",
country: "NL",
houseNumberOrName: "1",
postalCode: "2312aa",
stateOrProvince: "NA",
street: "Street",
},
"contractTypes": [
"RECURRING"
contractTypes: [
"RECURRING",
],
"creationDate": "2017-10-10T08:50:02+02:00",
"firstPspReference": "8515076181707110",
"paymentMethodVariant": "paypal",
"recurringDetailReference": "8315076181982020",
"tokenDetails": {
"tokenData": {
creationDate: "2017-03-01T10:53:11.000",
firstPspReference: "8515076181707110",
paymentMethodVariant: "paypal",
recurringDetailReference: "8315076181982020",
tokenDetails: {
tokenData: {
"BillingAgreementId": "B-7MA42752FE774625C",
"EmailId": "tedtest@test.nl",
"PayPal.PayerId": "H95EPL8B2KFE6",
"BillingAgreementId": "B-7MA42752FE774625C"
},
"tokenDataType": "PayPal"
tokenDataType: "PayPal",
},
"variant": "paypal"
}
variant: "paypal",
},
],
"shopperReference": "test-123",
"invalidOneclickContracts": "false"
};

View File

@@ -1,28 +0,0 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const notifyShopperSuccess = {
"message": "Request Processed Successfully",
"resultCode": "Success",
"shopperNotificationReference": "9915003646742627",
"storedPaymentMethodId": "8415995487234100",
"pspReference": "9915003646742627",
"reference": "Example reference",
"displayedReference": "Example displayed reference"
};

View File

@@ -1,20 +1 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const asyncRes = "ok";

View File

@@ -1,23 +1,4 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const localSecuredRes = {
export const localSecuredRes = JSON.stringify({
SaleToPOIResponse: {
MessageHeader: {
MessageCategory: "Payment",
@@ -28,11 +9,326 @@ export const localSecuredRes = {
SaleID: "325488592",
ServiceID: "325488592"
},
PaymentResponse: {}
paymentResponse: {
paymentReceipt: [
{
documentQualifier: "CashierReceipt",
outputContent: {
outputFormat: "Text",
outputText: [
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "key=header1"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "key=header2"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=MERCHANT%20COPY&key=merchantTitle"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Date&value=08%2f05%2f19&key=txdate"
},
{
endOfLineFlag: true,
text: "name=Time&value=15%3a25%3a15&key=txtime"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Card&value=%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a0010&key=pan"
},
{
endOfLineFlag: true,
text: "name=PAN%20seq.&value=01&key=panSeq"
},
{
endOfLineFlag: true,
text: "name=Pref.%20name&value=PPC%20MCD%2001%20v2%202&key=preferredName"
},
{
endOfLineFlag: true,
text: "name=Card%20type&value=mc&key=cardType"
},
{
endOfLineFlag: true,
text: "name=Payment%20method&value=mc&key=paymentMethod"
},
{
endOfLineFlag: true,
text: "name=Payment%20variant&value=mc&key=paymentMethodVariant"
},
{
endOfLineFlag: true,
text: "name=Entry%20mode&value=Contactless%20chip&key=posEntryMode"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=AID&value=A0000000041010&key=aid"
},
{
endOfLineFlag: true,
text: "name=MID&value=1000&key=mid"
},
{
endOfLineFlag: true,
text: "name=TID&value=P400Plus-275039202&key=tid"
},
{
endOfLineFlag: true,
text: "name=PTID&value=75039202&key=ptid"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Auth.%20code&value=123456&key=authCode"
},
{
endOfLineFlag: true,
text: "name=Tender&value=4r7i001557325515012&key=txRef"
},
{
endOfLineFlag: true,
text: "name=Reference&value=999&key=mref"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Type&value=GOODS_SERVICES&key=txtype"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=TOTAL&value=%e2%82%ac%c2%a01.00&key=totalAmount"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=APPROVED&key=approved"
}
]
},
requiredSignatureFlag: false
},
{
documentQualifier: "CustomerReceipt",
outputContent: {
outputFormat: "Text",
outputText: [
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "key=header1"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "key=header2"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=CARDHOLDER%20COPY&key=cardholderHeader"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Date&value=08%2f05%2f19&key=txdate"
},
{
endOfLineFlag: true,
text: "name=Time&value=15%3a25%3a15&key=txtime"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Card&value=%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a0010&key=pan"
},
{
endOfLineFlag: true,
text: "name=PAN%20seq.&value=01&key=panSeq"
},
{
endOfLineFlag: true,
text: "name=Pref.%20name&value=PPC%20MCD%2001%20v2%202&key=preferredName"
},
{
endOfLineFlag: true,
text: "name=Card%20type&value=mc&key=cardType"
},
{
endOfLineFlag: true,
text: "name=Payment%20method&value=mc&key=paymentMethod"
},
{
endOfLineFlag: true,
text: "name=Payment%20variant&value=mc&key=paymentMethodVariant"
},
{
endOfLineFlag: true,
text: "name=Entry%20mode&value=Contactless%20chip&key=posEntryMode"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=AID&value=A0000000041010&key=aid"
},
{
endOfLineFlag: true,
text: "name=MID&value=1000&key=mid"
},
{
endOfLineFlag: true,
text: "name=TID&value=P400Plus-275039202&key=tid"
},
{
endOfLineFlag: true,
text: "name=PTID&value=75039202&key=ptid"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Auth.%20code&value=123456&key=authCode"
},
{
endOfLineFlag: true,
text: "name=Tender&value=4r7i001557325515012&key=txRef"
},
{
endOfLineFlag: true,
text: "name=Reference&value=999&key=mref"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Type&value=GOODS_SERVICES&key=txtype"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=TOTAL&value=%e2%82%ac%c2%a01.00&key=totalAmount"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
characterStyle: "Bold",
endOfLineFlag: true,
text: "name=APPROVED&key=approved"
},
{
endOfLineFlag: true,
text: "key=filler"
},
{
endOfLineFlag: true,
text: "name=Please%20retain%20for%20your%20records&key=retain"
},
{
endOfLineFlag: true,
text: "name=Thank%20you&key=thanks"
}
]
},
requiredSignatureFlag: false
}
],
paymentResult: {
amountsResp: {
authorizedAmount: 1,
currency: "EUR"
},
onlineFlag: true,
paymentAcquirerData: {
acquirerPoiid: "P400Plus-275039202",
acquirerTransactionId: {
timeStamp: "2019-05-08T14:25:15.000Z",
transactionId: "8815573255107661"
},
approvalCode: "123456",
merchantId: "TestMerchantRenatoTest"
},
paymentInstrumentData: {
cardData: {
cardCountryCode: "056",
entryMode: [
"Contactless"
],
maskedPan: "541333 **** 0010",
paymentBrand: "mc",
sensitiveCardData: {
cardSeqNumb: "01",
expiryDate: "1225"
}
},
paymentInstrumentType: "Card"
}
},
poiData: {
poiReconciliationId: "1000",
poiTransactionId: {
timeStamp: "2019-05-08T14:25:15.000Z",
transactionId: "4r7i001557325515012.8815573255107661"
}
},
response: {
additionalResponse: "tid=75039202&AID=A0000000041010&transactionType=GOODS_SERVICES&backendGiftcardIndicator=false&expiryYear=2025&acquirerAccountCode=TestPmmAcquirerAccount&alias=K182596230843790&posOriginalAmountCurrency=EUR&giftcardIndicator=false&authorisedAmountValue=100&pspReference=8815573255107661&paymentMethodVariant=mc&cardHolderName=N%2fA&refusalReasonRaw=APPROVED&authorisationMid=1000&expiryDate=12%2f2025&applicationPreferredName=PPC%20MCD%2001%20v2%202&isCardCommercial=unknown&acquirerCode=TestPmmAcquirer&txtime=15%3a25%3a15&iso8601TxDate=2019-05-08T14%3a25%3a15.0000000%2b0000&cardType=mc&posOriginalAmountValue=100&offline=false&aliasType=Default&txdate=08-05-2019&paymentMethod=mc&cvcResult=0%20Unknown&startYear=2030&tc=A767D7547D930504&avsResult=0%20Unknown&cardIssueNumber=1&mid=1000&merchantReference=999&transactionReferenceNumber=8815573255107661&expiryMonth=12&cardSummary=0010&posTotalAmountValue=100&posAuthAmountCurrency=EUR&cardHolderVerificationMethodResults=1F0302&authCode=123456&cardIssuerCountryId=056&shopperCountry=NL&posEntryMode=CLESS_CHIP&startMonth=34&fundingSource=CREDIT&cardScheme=mc&cardBin=541333&posAuthAmountValue=100",
result: "Success"
},
saleData: {
saleTransactionId: {
timeStamp: "2019-05-08T14:24:48.598Z",
transactionId: "999"
}
}
}
}
};
});
export const localEncRes = {
export const localEncRes = JSON.stringify({
SaleToPOIResponse: {
MessageHeader: {
MessageCategory: "Payment",
@@ -138,9 +434,9 @@ export const localEncRes = {
Nonce: "9iiJMpzKfYs3106ozIKNFQ==",
},
},
};
});
export const wrongEncRes = {
export const wrongEncRes = JSON.stringify({
SaleToPOIResponse: {
MessageHeader: {
MessageCategory: "Payment",
@@ -246,4 +542,4 @@ export const wrongEncRes = {
Nonce: "9iiJMpzKfYs3106ozIKNFQ==",
},
},
};
});

View File

@@ -1,32 +1,13 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
export const syncRes = {
export const syncRes = JSON.stringify({
SaleToPOIResponse: {
MessageHeader: {
MessageCategory: "Payment",
MessageClass: "Service",
MessageType: "Response",
POIID: process.env.ADYEN_TERMINAL_POIID,
POIID: "P400Plus-123456789",
ProtocolVersion: "3.0",
SaleID: "001",
ServiceID: "001",
ServiceID: "1234567890",
},
PaymentResponse: {
POIData: {
@@ -345,44 +326,4 @@ export const syncRes = {
},
},
},
};
export const syncRefund = {
SaleToPOIResponse: {
MessageHeader: {
MessageCategory: "Payment",
MessageClass: "Service",
MessageType: "Response",
POIID: process.env.ADYEN_TERMINAL_POIID,
ProtocolVersion: "3.0",
SaleID: "001",
ServiceID: "001",
},
ReversalResponse: {
Response: {
Result: "Success"
}
}
}
};
export const syncResEventNotification = {
SaleToPOIRequest: {
EventNotification: {
EventToNotify: "Reject",
EventDetails: "message=Did+not+receive+a+response+from+the+POI.",
RejectedMessage: "ewoi...0KfQo=",
TimeStamp: "2020-03-31T10:28:39.515Z"
},
MessageHeader: {
DeviceID: "666568147",
MessageCategory: "Event",
MessageClass: "Event",
MessageType: "Notification",
POIID: "P400Plus-123456789",
ProtocolVersion: "3.0",
SaleID: "saleid-4c32759faaa7",
ServiceID: "31122609"
}
}
};
});

View File

@@ -1,135 +0,0 @@
export const transfersSuccess = {
"id" : "1W1UG35U8A9J5ZLG",
"amount" : {
"value" : 110000,
"currency" : "EUR"
},
"balanceAccountId" : "BAB8B2C3D4E5F6G7H8D9J6GD4",
"category" : "bank",
"counterparty" : {
"accountHolder" : {
"fullName" : "A. Klaassen",
"address" : {
"city" : "San Francisco",
"country" : "US",
"postalCode" : "94678",
"stateOrProvince" : "CA",
"street" : "Brannan Street",
"street2" : "274"
}
},
"accountIdentification" : {
"type" : "numberBic",
"accountNumber" : "123456789",
"bic" : "BOFAUS3NXXX"
}
},
"priority" : "wire",
"referenceForBeneficiary" : "Your reference sent to the beneficiary",
"reference" : "Your internal reference for the transfer",
"description" : "Your description for the transfer",
"direction" : "outgoing",
"reason" : "approved",
"status" : "authorised"
};
export const getTransactionSuccess = {
"accountHolderId" : "AHA1B2C3D4E5F6G7H8I9J0",
"amount" : {
"currency" : "EUR",
"value" : 9887
},
"balanceAccountId" : "BAB8B2C3D4E5F6G7H8D9J6GD4",
"balancePlatform" : "YOUR_BALANCE_PLATFORM",
"bookingDate" : "2022-03-14T12:01:00+01:00",
"category" : "bank",
"counterparty" : {
"balanceAccountId" : "NL29ADYX0000000001"
},
"createdAt" : "2022-03-14T12:01:00+01:00",
"description" : "YOUR_DESCRIPTION",
"id" : "IZK7C25U7DYVX03Y",
"instructedAmount" : {
"currency" : "EUR",
"value" : 9887
},
"reference" : "2L6C6B5U7DYULLXC",
"referenceForBeneficiary" : "YOUR_REFERENCE_FOR_BENEFICIARY",
"status" : "booked",
"transferId" : "2QP32A5U7IWC5WKG",
"type" : "bankTransfer",
"valueDate" : "2022-03-14T12:01:00+01:00"
};
export const listTransactionsSuccess = {
"data" : [
{
"accountHolderId" : "AHA1B2C3D4E5F6G7H8I9J0",
"amount" : {
"currency" : "EUR",
"value" : -9
},
"balanceAccountId" : "BAB8B2C3D4E5F6G7H8D9J6GD4",
"balancePlatform" : "YOUR_BALANCE_PLATFORM",
"bookingDate" : "2022-03-11T11:21:24+01:00",
"category" : "internal",
"createdAt" : "2022-03-11T11:21:24+01:00",
"id" : "1VVF0D5U66PIUIVP",
"instructedAmount" : {
"currency" : "EUR",
"value" : -9
},
"reference" : "REFERENCE_46e8c40e",
"status" : "booked",
"transferId" : "1VVF0D5U66PIUIVP",
"type" : "fee",
"valueDate" : "2022-03-11T11:21:24+01:00"
},
{
"accountHolderId" : "AHA1B2C3D4E5F6G7H8I9J0",
"amount" : {
"currency" : "EUR",
"value" : -46
},
"balanceAccountId" : "BAB8B2C3D4E5F6G7H8D9J6GD4",
"balancePlatform" : "YOUR_BALANCE_PLATFORM",
"bookingDate" : "2022-03-12T14:22:52+01:00",
"category" : "internal",
"createdAt" : "2022-03-12T14:22:52+01:00",
"id" : "1WEPGD5U6MS1CFK3",
"instructedAmount" : {
"currency" : "EUR",
"value" : -46
},
"reference" : "YOUR_REFERENCE",
"status" : "booked",
"transferId" : "1WEPGD5U6MS1CFK3",
"type" : "fee",
"valueDate" : "2022-03-12T14:22:52+01:00"
},
{
"accountHolderId" : "AHA1B2C3D4E5F6G7H8I9J0",
"amount" : {
"currency" : "EUR",
"value" : -8
},
"balanceAccountId" : "BAB8B2C3D4E5F6G7H8D9J6GD4",
"balancePlatform" : "YOUR_BALANCE_PLATFORM",
"bookingDate" : "2022-03-14T21:00:48+01:00",
"createdAt" : "2022-03-14T15:00:00+01:00",
"description" : "YOUR_DESCRIPTION_2",
"id" : "2QP32A5U7IWC5WKG",
"instructedAmount" : {
"currency" : "EUR",
"value" : -8
},
"status" : "booked",
"valueDate" : "2022-03-14T21:00:48+01:00"
}
],
"_links" : {
"next" : {
"href" : "https://balanceplatform-api-test.adyen.com/btl/v2/transactions?balancePlatform=Bastronaut&createdUntil=2022-03-21T00%3A00%3A00Z&createdSince=2022-03-11T00%3A00%3A00Z&limit=3&cursor=S2B-TSAjOkIrYlIlbjdqe0RreHRyM32lKRSxubXBHRkhHL2E32XitQQz5SfzpucD5HbHwpM1p6NDR1eXVQLFF6MmY33J32sobDxQYT90MHIud1hwLnd6JitcX32xJ"
}
}
};

View File

@@ -1,894 +0,0 @@
import nock from "nock";
import Client from "../client";
import { createClient } from "../__mocks__/base";
import BalancePlatform from "../services/balancePlatform";
import { balancePlatform } from "../typings";
import { AccountHolderUpdate } from "../services/balancePlaftform/accountHolders";
import { SweepConfigurationV2Create, SweepConfigurationV2Update } from "../services/balancePlaftform/balanceAccounts";
import { TransactionRuleInfoUpdate } from "../services/balancePlaftform/transactionRules";
let client: Client;
let balancePlatformService: BalancePlatform;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.balancePlatformEndpoint}/${Client.BALANCE_PLATFORM_API_VERSION}`);
balancePlatformService = new BalancePlatform(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("Balance Platform", (): void => {
const balanceAccountId = "BA32272223222B59CZ3T52DKZ";
const sweepId = "SWPC4227C224555B5FTD2NT2JV4WN5";
const paymentInstrumentId = "PI32272223222B5CMD3MQ3HXX";
const paymentInstrumentGroupId = "PG3227C223222B5CMD3FJFKGZ";
const transactionRuleId = "TR3227C223222B5FCB756DV9H";
describe("AccountHolders", (): void => {
it("should support POST /accountHolders", async (): Promise<void> => {
scope.post("/accountHolders")
.reply(200, {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"contactDetails": {
"email": "s.hopper@example.com",
"phone": {
"number": "+315551231234",
"type": "Mobile"
},
"address": {
"city": "Amsterdam",
"country": "NL",
"street": "Brannan Street",
"houseNumberOrName": "274",
"postalCode": "1020CD"
}
},
"description": "S.Hopper - Staff 123",
"legalEntityId": "LE322KT223222D5FJ7THR293F",
"id": "AH3227C223222B5CMD2SXFKGT",
"status": "active"
});
const request: balancePlatform.AccountHolderInfo = {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"description": "S.Hopper - Staff 123",
"legalEntityId": "LE322KT223222D5FJ7THR293F",
"contactDetails": {
"email": "s.hopper@example.com",
"phone": {
"number": "+315551231234",
"type": balancePlatform.Phone.TypeEnum.Mobile
},
"address": {
"city": "Amsterdam",
"country": "NL",
"street": "Brannan Street",
"houseNumberOrName": "274",
"postalCode": "1020CD"
}
}
};
const response: balancePlatform.AccountHolder = await balancePlatformService.AccountHolders.create(request);
expect(response.id).toBe("AH3227C223222B5CMD2SXFKGT");
expect(response.legalEntityId).toBe("LE322KT223222D5FJ7THR293F");
});
it("should support GET /accountHolders/{id}", async (): Promise<void> => {
scope.get("/accountHolders/AH32272223222B5CM4MWJ892H")
.reply(200, {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"contactDetails": {
"address": {
"city": "Amsterdam",
"country": "NL",
"houseNumberOrName": "274",
"postalCode": "1020CD",
"street": "Brannan Street"
},
"email": "s.hopper@example.com",
"phone": {
"number": "+315551231234",
"type": "Mobile"
}
},
"description": "S.Hopper - Staff 123",
"id": "AH32272223222B5CM4MWJ892H",
"status": "Active"
});
const response: balancePlatform.AccountHolder = await balancePlatformService.AccountHolders.retrieve("AH32272223222B5CM4MWJ892H");
expect(response.id).toBe("AH32272223222B5CM4MWJ892H");
expect(response.balancePlatform).toBe("YOUR_BALANCE_PLATFORM");
});
it("should support PATCH /accountHolders/{id}", async (): Promise<void> => {
scope.patch("/accountHolders/AH32272223222B5CM4MWJ892H")
.reply(200, {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"contactDetails": {
"address": {
"city": "Amsterdam",
"country": "NL",
"houseNumberOrName": "274",
"postalCode": "1020CD",
"street": "Brannan Street"
},
"email": "s.hopper@example.com",
"phone": {
"number": "+315551231234",
"type": "Mobile"
}
},
"description": "S.Hopper - Staff 123",
"id": "AH32272223222B5CM4MWJ892H",
"status": "Suspended"
});
const request: AccountHolderUpdate = {
status: balancePlatform.AccountHolder.StatusEnum.Suspended,
legalEntityId: "LE322KT223222D5FJ7THR293F",
};
const response: balancePlatform.AccountHolder = await balancePlatformService.AccountHolders.update("AH32272223222B5CM4MWJ892H", request);
expect(response.status).toBe("Suspended");
});
it("should support GET /accountHolders/{id}/balanceAccounts", async (): Promise<void> => {
scope.get("/accountHolders/AH32272223222B5CM4MWJ892H/balanceAccounts?limit=5&offset=10")
.reply(200, {
"balanceAccounts": [
{
"accountHolderId": "AH32272223222B59K6ZKBBFNQ",
"defaultCurrencyCode": "EUR",
"id": "BA32272223222B59K6ZXHBFN6",
"status": "Active"
},
{
"accountHolderId": "AH32272223222B59K6ZKBBFNQ",
"defaultCurrencyCode": "EUR",
"id": "BA32272223222B59K72CKBFNJ",
"status": "Active"
},
{
"accountHolderId": "AH32272223222B59K6ZKBBFNQ",
"defaultCurrencyCode": "EUR",
"id": "BA32272223222B5BRR27B2M7G",
"status": "Active"
}
],
"hasNext": true,
"hasPrevious": false
});
const response: balancePlatform.PaginatedBalanceAccountsResponse = await balancePlatformService.AccountHolders.listBalanceAccounts("AH32272223222B5CM4MWJ892H", {
params: {
"limit": "5",
"offset": "10"
}
});
expect(response.balanceAccounts[0].id).toBe("BA32272223222B59K6ZXHBFN6");
});
});
describe("BalanceAccounts", (): void => {
it("should support POST /balanceAccounts", async (): Promise<void> => {
scope.post("/balanceAccounts")
.reply(200, {
"accountHolderId": "AH32272223222B59K6ZKBBFNQ",
"defaultCurrencyCode": "EUR",
"reference": "S.Hopper - Main balance account",
"balances": [
{
"available": 0,
"balance": 0,
"currency": "EUR",
"reserved": 0
}
],
"id": balanceAccountId,
"status": "active"
});
const request: balancePlatform.BalanceAccountInfo = {
"accountHolderId": "AH32272223222B59K6ZKBBFNQ",
"description": "S.Hopper - Main balance account"
};
const response: balancePlatform.BalanceAccount = await balancePlatformService.BalanceAccounts.create(request);
expect(response.id).toBe(balanceAccountId);
});
it("should support GET /balanceAccounts/{balanceAccountId}/sweeps", async (): Promise<void> => {
scope.get(`/balanceAccounts/${balanceAccountId}/sweeps?limit=5&offset=10`)
.reply(200, {
"hasNext": false,
"hasPrevious": false,
"sweeps": [
{
"id": sweepId,
"schedule": {
"type": "daily"
},
"status": "active",
"targetAmount": {
"currency": "EUR",
"value": 0
},
"triggerAmount": {
"currency": "EUR",
"value": 0
},
"type": "push",
"counterparty": {
"balanceAccountId": "BA32272223222B5FTD2KR6TJD"
},
"currency": "EUR"
}
]
});
const response: balancePlatform.BalanceSweepConfigurationsResponse = await balancePlatformService.BalanceAccounts.listSweeps(balanceAccountId, {
params: {
"limit": "5",
"offset": "10"
}
});
expect(response.hasNext).toBeFalsy();
expect(response.sweeps.length).toBe(1);
});
it("should support POST /balanceAccounts/{balanceAccountId}/sweeps", async (): Promise<void> => {
scope.post(`/balanceAccounts/${balanceAccountId}/sweeps`)
.reply(200, {
"id": sweepId,
"counterparty": {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
},
"triggerAmount": {
"currency": "EUR",
"value": 50000
},
"currency": "EUR",
"schedule": {
"type": "balance"
},
"type": "pull",
"status": "active"
});
const request: SweepConfigurationV2Create = {
"counterparty": {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
},
"triggerAmount": {
"currency": "EUR",
"value": 50000
},
"currency": "EUR",
"schedule": {
"type": balancePlatform.SweepSchedule.TypeEnum.Balance
},
"type": balancePlatform.SweepConfigurationV2.TypeEnum.Pull,
"status": balancePlatform.SweepConfigurationV2.StatusEnum.Active
};
const response: balancePlatform.SweepConfigurationV2 = await balancePlatformService.BalanceAccounts.createSweep(balanceAccountId, request);
expect(response.id).toBe(sweepId);
expect(response.triggerAmount!.value).toBe(50000);
});
it("should support DELETE /balanceAccounts/{balanceAccountId}/sweeps/{sweepId}", async (): Promise<void> => {
scope.delete(`/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`).reply(204);
await balancePlatformService.BalanceAccounts.deleteSweep(balanceAccountId, sweepId);
});
it("should support GET /balanceAccounts/{balanceAccountId}/sweeps/{sweepId}", async (): Promise<void> => {
scope.get(`/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`)
.reply(200, {
"id": sweepId,
"schedule": {
"type": "daily"
},
"status": "active",
"targetAmount": {
"currency": "EUR",
"value": 0
},
"triggerAmount": {
"currency": "EUR",
"value": 0
},
"type": "push",
"counterparty": {
"balanceAccountId": "BA32272223222B5FTD2KR6TJD"
},
"currency": "EUR"
});
const response: balancePlatform.SweepConfigurationV2 = await balancePlatformService.BalanceAccounts.retrieveSweep(balanceAccountId, sweepId);
expect(response.id).toBe(sweepId);
expect(response.status).toBe("active");
});
it("should support PATCH /balanceAccounts/{balanceAccountId}/sweeps/{sweepId}", async (): Promise<void> => {
scope.patch(`/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`)
.reply(200, {
"id": sweepId,
"counterparty": {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
},
"triggerAmount": {
"currency": "EUR",
"value": 50000
},
"currency": "EUR",
"schedule": {
"type": "balance"
},
"type": "pull",
"status": "inactive"
});
const request: SweepConfigurationV2Update = {
"status": balancePlatform.SweepConfigurationV2.StatusEnum.Inactive
};
const response: balancePlatform.SweepConfigurationV2 = await balancePlatformService.BalanceAccounts.updateSweep(balanceAccountId, sweepId, request);
expect(response.status).toBe("inactive");
});
it("should support GET /balanceAccounts/{id}", async (): Promise<void> => {
scope.get(`/balanceAccounts/${balanceAccountId}`)
.reply(200, {
"accountHolderId": "AH32272223222B59K6RTQBFNZ",
"defaultCurrencyCode": "EUR",
"balances": [
{
"available": 0,
"balance": 0,
"currency": "EUR",
"reserved": 0
}
],
"id": balanceAccountId,
"status": "Active"
});
const response: balancePlatform.BalanceAccount = await balancePlatformService.BalanceAccounts.retrieve(balanceAccountId);
expect(response.id).toBe(balanceAccountId);
expect(response.status).toBe("Active");
});
it("should support PATCH /balanceAccounts/{id}", async (): Promise<void> => {
scope.patch(`/balanceAccounts/${balanceAccountId}`)
.reply(200, {
"accountHolderId": "string",
"balances": [
{
"available": 0,
"balance": 0,
"currency": "string",
"reserved": 0
}
],
"defaultCurrencyCode": "string",
"description": "Testing",
"id": "string",
"reference": "string",
"status": "active",
"timeZone": "Europe/Amsterdam"
});
const request: balancePlatform.BalanceAccountUpdateRequest = {
"description": "Testing",
"status": balancePlatform.BalanceAccountUpdateRequest.StatusEnum.Active,
"timeZone": "Europe/Amsterdam"
};
const response: balancePlatform.BalanceAccount = await balancePlatformService.BalanceAccounts.update(balanceAccountId, request);
expect(response.status).toBe("active");
expect(response.timeZone).toBe("Europe/Amsterdam");
});
it("should support GET /balanceAccounts/{id}/paymentInstruments", async (): Promise<void> => {
scope.get(`/balanceAccounts/${balanceAccountId}/paymentInstruments?limit=3&offset=6`)
.reply(200, {
"hasNext": "true",
"hasPrevious": "false",
"paymentInstruments": [
{
"balanceAccountId": balanceAccountId,
"issuingCountryCode": "GB",
"status": "Active",
"type": "card",
"card": {
"brandVariant": "mc",
"cardholderName": "name",
"formFactor": "virtual",
"bin": "555544",
"expiration": {
"month": "12",
"year": "2022"
},
"lastFour": "2357",
"number": "************2357"
},
"id": "PI32272223222B59M5TM658DT"
},
{
"balanceAccountId": balanceAccountId,
"issuingCountryCode": "GB",
"status": "Active",
"type": "card",
"card": {
"brandVariant": "mc",
"cardholderName": "name",
"formFactor": "virtual",
"bin": "555544",
"expiration": {
"month": "01",
"year": "2023"
},
"lastFour": "8331",
"number": "************8331"
},
"id": "PI32272223222B59PXDGQDLSF"
}
]
});
const response: balancePlatform.PaginatedPaymentInstrumentsResponse = await balancePlatformService.BalanceAccounts.listPaymentInstruments(balanceAccountId, {
params: {
limit: "3",
offset: "6",
}
});
expect(response.paymentInstruments.length).toBe(2);
expect(response.paymentInstruments[0].id).toBe("PI32272223222B59M5TM658DT");
});
});
describe("General", (): void => {
it("should support GET /balancePlatforms/{id}", async (): Promise<void> => {
scope.get(`/balancePlatforms/${balanceAccountId}`)
.reply(200, {
"id": balanceAccountId,
"status": "Active"
});
const response: balancePlatform.BalancePlatform = await balancePlatformService.General.retrieve(balanceAccountId);
expect(response.id).toBe(balanceAccountId);
expect(response.status).toBe("Active");
});
it("should support GET /balancePlatforms/{id}/accountHolders", async (): Promise<void> => {
scope.get(`/balancePlatforms/${balanceAccountId}/accountHolders`)
.reply(200, {
"accountHolders": [
{
"contactDetails": {
"address": {
"city": "Amsterdam",
"country": "NL",
"houseNumberOrName": "6",
"postalCode": "12336750",
"street": "Simon Carmiggeltstraat"
}
},
"description": "J. Doe",
"id": "AH32272223222B59DDWSCCMP7",
"status": "Active"
},
{
"contactDetails": {
"address": {
"city": "Amsterdam",
"country": "NL",
"houseNumberOrName": "11",
"postalCode": "12336750",
"street": "Simon Carmiggeltstraat"
}
},
"description": "S. Hopper",
"id": "AH32272223222B59DJ7QBCMPN",
"status": "Active"
}
],
"hasNext": "true",
"hasPrevious": "false"
});
const response: balancePlatform.PaginatedAccountHoldersResponse = await balancePlatformService.General.listAccountHolders(balanceAccountId);
expect(response.accountHolders.length).toBe(2);
expect(response.accountHolders[0].id).toBe("AH32272223222B59DDWSCCMP7");
});
});
describe("PaymentInstruments", (): void => {
it("should support POST /paymentInstruments", async (): Promise<void> => {
scope.post("/paymentInstruments")
.reply(200, {
"balanceAccountId": balanceAccountId,
"description": "S. Hopper - Main card",
"issuingCountryCode": "GB",
"status": "Active",
"type": "card",
"card": {
"brand": "mc",
"brandVariant": "mcdebit",
"cardholderName": "Simon Hopper",
"formFactor": "virtual",
"bin": "555544",
"cvc": "873",
"expiration": {
"month": "01",
"year": "2024"
},
"lastFour": "3548"
},
"id": paymentInstrumentId
});
const request: balancePlatform.PaymentInstrumentInfo = {
"type": balancePlatform.PaymentInstrumentInfo.TypeEnum.Card,
"issuingCountryCode": "NL",
"balanceAccountId": balanceAccountId,
"status": balancePlatform.PaymentInstrumentInfo.StatusEnum.Inactive,
"card": {
"formFactor": balancePlatform.CardInfo.FormFactorEnum.Physical,
"brand": "mc",
"brandVariant": "mcdebit",
"cardholderName": "Sam Hopper",
"deliveryContact": {
"address": {
"city": "Amsterdam",
"country": "NL",
"stateOrProvince": "NH",
"line1": "Simon Carmiggeltstraat",
"line2": "6-50",
"postalCode": "1011DJ"
},
"name": {
"firstName": "Sam",
"lastName": "Hopper"
}
},
"configuration": {
"configurationProfileId": "YOUR_CONFIGURATION_PROFILE_ID"
},
},
"description": "S.Hopper - Main card"
};
const response: balancePlatform.PaymentInstrument = await balancePlatformService.PaymentInstruments.create(request);
expect(response.id).toBe(paymentInstrumentId);
expect(response.balanceAccountId).toBe(balanceAccountId);
});
it("should support GET /paymentInstruments/{id}", async (): Promise<void> => {
scope.get(`/paymentInstruments/${paymentInstrumentId}`)
.reply(200, {
"balanceAccountId": balanceAccountId,
"description": "S. Hopper - Main card",
"issuingCountryCode": "GB",
"status": "active",
"type": "card",
"card": {
"brand": "mc",
"brandVariant": "mcdebit",
"cardholderName": "Simon Hopper",
"formFactor": "virtual",
"bin": "555544",
"expiration": {
"month": "01",
"year": "2024"
},
"lastFour": "3548",
"number": "************3548"
},
"id": paymentInstrumentId
});
const response: balancePlatform.PaymentInstrument = await balancePlatformService.PaymentInstruments.retrieve(paymentInstrumentId);
expect(response.id).toBe(paymentInstrumentId);
expect(response.status).toBe("active");
});
it("should support PATCH /paymentInstruments/{id}", async (): Promise<void> => {
scope.patch(`/paymentInstruments/${paymentInstrumentId}`)
.reply(200, {
"balanceAccountId": "BA32272223222B5CM82WL892M",
"description": "S. Hopper - Main card",
"issuingCountryCode": "GB",
"status": "inactive",
"type": "card",
"card": {
"brand": "mc",
"brandVariant": "mcdebit",
"cardholderName": "Simon Hopper",
"formFactor": "virtual",
"bin": "555544",
"expiration": {
"month": "01",
"year": "2024"
},
"lastFour": "5785",
"number": "************5785"
},
"id": paymentInstrumentId
});
const request: balancePlatform.PaymentInstrumentUpdateRequest = {
"balanceAccountId": "BA32272223222B5CM82WL892M"
};
const response: balancePlatform.PaymentInstrument = await balancePlatformService.PaymentInstruments.update(paymentInstrumentId, request);
expect(response.id).toBe(paymentInstrumentId);
expect(response.balanceAccountId).toBe("BA32272223222B5CM82WL892M");
});
it("should support GET /paymentInstruments/{id}/transactionRules", async (): Promise<void> => {
scope.get(`/paymentInstruments/${paymentInstrumentId}/transactionRules`)
.reply(200, {
"transactionRules": [
{
"description": "Allow 5 transactions per month",
"interval": {
"type": "monthly"
},
"maxTransactions": 5,
"paymentInstrumentGroupId": paymentInstrumentGroupId,
"reference": "myRule12345",
"startDate": "2021-01-25T12:46:35.476629Z",
"status": "active",
"type": "velocity",
"id": "TR32272223222B5CMDGMC9F4F"
},
{
"amount": {
"currency": "EUR",
"value": 10000
},
"description": "Allow up to 100 EUR per month",
"interval": {
"type": "monthly"
},
"paymentInstrumentGroupId": paymentInstrumentGroupId,
"reference": "myRule16378",
"startDate": "2021-01-25T12:46:35.476629Z",
"status": "active",
"type": "velocity",
"id": "TR32272223222B5CMDGT89F4F"
}
]
});
const response: balancePlatform.TransactionRulesResponse = await balancePlatformService.PaymentInstruments.listTransactionRules(paymentInstrumentId);
expect(response.transactionRules!.length).toBe(2);
expect(response.transactionRules![0].id).toBe("TR32272223222B5CMDGMC9F4F");
});
});
describe("PaymentInstrumentGroups", (): void => {
it("should support POST /paymentInstrumentGroups", async (): Promise<void> => {
scope.post("/paymentInstrumentGroups")
.reply(200, {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"txVariant": "mc",
"id": paymentInstrumentGroupId
});
const request: balancePlatform.PaymentInstrumentGroupInfo = {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"txVariant": "mc"
};
const response: balancePlatform.PaymentInstrumentGroup = await balancePlatformService.PaymentInstrumentGroups.create(request);
expect(response.id).toBe(paymentInstrumentGroupId);
expect(response.txVariant).toBe("mc");
});
it("should support GET /paymentInstrumentGroups/{id}", async (): Promise<void> => {
scope.get(`/paymentInstrumentGroups/${paymentInstrumentGroupId}`)
.reply(200, {
"balancePlatform": "YOUR_BALANCE_PLATFORM",
"txVariant": "mc",
"id": paymentInstrumentGroupId
});
const response: balancePlatform.PaymentInstrumentGroup = await balancePlatformService.PaymentInstrumentGroups.retrieve(paymentInstrumentGroupId);
expect(response.id).toBe(paymentInstrumentGroupId);
expect(response.txVariant).toBe("mc");
});
it("should support GET /paymentInstrumentGroups/{id}/transactionRules", async (): Promise<void> => {
scope.get(`/paymentInstrumentGroups/${paymentInstrumentGroupId}/transactionRules`)
.reply(200, {
"transactionRules": [
{
"description": "Allow 5 transactions per month",
"interval": {
"type": "monthly"
},
"maxTransactions": 5,
"paymentInstrumentGroupId": paymentInstrumentGroupId,
"reference": "myRule12345",
"startDate": "2021-01-25T12:46:35.476629Z",
"status": "active",
"type": "velocity",
"id": "TR32272223222B5CMDGMC9F4F"
},
{
"amount": {
"currency": "EUR",
"value": 10000
},
"description": "Allow up to 100 EUR per month",
"interval": {
"type": "monthly"
},
"paymentInstrumentGroupId": paymentInstrumentGroupId,
"reference": "myRule16378",
"startDate": "2021-01-25T12:46:35.476629Z",
"status": "active",
"type": "velocity",
"id": "TR32272223222B5CMDGT89F4F"
}
]
});
const response: balancePlatform.TransactionRulesResponse = await balancePlatformService.PaymentInstrumentGroups.listTransactionRules(paymentInstrumentGroupId);
expect(response.transactionRules!.length).toBe(2);
expect(response.transactionRules![0].id).toBe("TR32272223222B5CMDGMC9F4F");
});
});
describe("TransactionRules", (): void => {
it("should support POST /transactionRules", async (): Promise<void> => {
scope.post("/transactionRules")
.reply(200, {
"description": "Allow only point-of-sale transactions",
"entityKey": {
"entityReference": "PI3227C223222B5BPCMFXD2XG",
"entityType": "paymentInstrument"
},
"interval": {
"timeZone": "UTC",
"type": "perTransaction"
},
"outcomeType": "hardBlock",
"reference": "YOUR_REFERENCE_4F7346",
"requestType": "authorization",
"ruleRestrictions": {
"processingTypes": {
"operation": "noneMatch",
"value": [
"pos"
]
}
},
"startDate": "2022-03-23T15:05:11.979433+01:00",
"status": "active",
"type": "blockList",
"id": transactionRuleId
});
const request: balancePlatform.TransactionRuleInfo = {
"description": "Allow only point-of-sale transactions",
"reference": "YOUR_REFERENCE_4F7346",
"entityKey": {
"entityType": "paymentInstrument",
"entityReference": "PI3227C223222B5BPCMFXD2XG"
},
"status": balancePlatform.TransactionRuleInfo.StatusEnum.Active,
"interval": {
"type": balancePlatform.TransactionRuleInterval.TypeEnum.PerTransaction
},
"ruleRestrictions": {
"processingTypes": {
"operation": "noneMatch",
"value": [
balancePlatform.ProcessingTypesRestriction.ValueEnum.Pos
]
}
},
"type": balancePlatform.TransactionRuleInfo.TypeEnum.BlockList
};
const response: balancePlatform.TransactionRule = await balancePlatformService.TransactionRules.create(request);
expect(response.id).toBe(transactionRuleId);
expect(response.status).toBe("active");
});
it("should support GET /transactionRules/{transactionRuleId}", async (): Promise<void> => {
scope.get(`/transactionRules/${transactionRuleId}`)
.reply(200, {
"transactionRule": {
"description": "Allow 5 transactions per month",
"interval": {
"type": "monthly"
},
"maxTransactions": 5,
"paymentInstrumentId": "PI3227C223222B59KGTXP884R",
"reference": "myRule12345",
"startDate": "2021-01-25T12:46:35.476629Z",
"status": "active",
"type": "velocity",
"id": transactionRuleId
}
});
const response: balancePlatform.TransactionRuleResponse = await balancePlatformService.TransactionRules.retrieve(transactionRuleId);
expect(response.transactionRule!.id).toBe(transactionRuleId);
expect(response.transactionRule!.type).toBe("velocity");
});
it("should support PATCH /transactionRules/{transactionRuleId}", async (): Promise<void> => {
scope.patch(`/transactionRules/${transactionRuleId}`)
.reply(200, {
"description": "Allow 5 transactions per month",
"interval": {
"type": "monthly"
},
"reference": "myRule12345",
"startDate": "2021-01-21T12:46:35.476629Z",
"status": "inactive",
"type": "velocity",
"id": transactionRuleId
});
const request: TransactionRuleInfoUpdate = {
"status": balancePlatform.TransactionRuleInfo.StatusEnum.Inactive
};
const response: balancePlatform.TransactionRule = await balancePlatformService.TransactionRules.update(transactionRuleId, request);
expect(response.status).toBe("inactive");
expect(response.reference).toBe("myRule12345");
});
it("should support DELETE /transactionRules/{transactionRuleId}", async (): Promise<void> => {
scope.delete(`/transactionRules/${transactionRuleId}`)
.reply(200, {
"amount": {
"currency": "EUR",
"value": 10000
},
"description": "Allow up to 100 EUR per month",
"interval": {
"type": "monthly"
},
"paymentInstrumentGroupId": "PG3227C223222B5CMD3FJFKGZ",
"reference": "myRule16378",
"startDate": "2021-01-25T12:46:35.476629Z",
"type": "velocity",
"id": transactionRuleId
});
const response: balancePlatform.TransactionRule = await balancePlatformService.TransactionRules.delete(transactionRuleId);
expect(response.id).toBe(transactionRuleId);
});
});
});

View File

@@ -1,40 +1,60 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen NodeJS API Library
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import nock from "nock";
import { createClient } from "../__mocks__/base";
import {createMockClientFromResponse} from "../__mocks__/base";
import BinLookup from "../services/binLookup";
import Client from "../client";
import HttpClientException from "../httpClient/httpClientException";
import { binlookup } from "../typings";
const threeDSAvailabilitySuccess = {
binDetails: {
issuerCountry: "NL"
},
dsPublicKeys: [{
brand: "visa",
directoryServerId: "F013371337",
publicKey: "eyJrdHkiOiJSU0EiLCJlIjoiQVFBQiIsIm4iOiI4VFBxZkFOWk4xSUEzcHFuMkdhUVZjZ1g4LUpWZ1Y0M2diWURtYmdTY0N5SkVSN3lPWEJqQmQyaTBEcVFBQWpVUVBXVUxZU1FsRFRKYm91bVB1aXVoeVMxUHN2NTM4UHBRRnEySkNaSERkaV85WThVZG9hbmlrU095c2NHQWtBVmJJWHA5cnVOSm1wTTBwZ0s5VGxJSWVHYlE3ZEJaR01OQVJLQXRKeTY3dVlvbVpXV0ZBbWpwM2d4SDVzNzdCR2xkaE9RUVlQTFdybDdyS0pLQlUwNm1tZlktUDNpazk5MmtPUTNEak02bHR2WmNvLThET2RCR0RKYmdWRGFmb29LUnVNd2NUTXhDdTRWYWpyNmQyZkppVXlqNUYzcVBrYng4WDl6a1c3UmlxVno2SU1qdE54NzZicmg3aU9Vd2JiWmoxYWF6VG1GQ2xEb0dyY2JxOV80Nnc9PSJ9"
}],
threeDS1Supported: true,
threeDS2CardRangeDetails: [],
threeDS2supported: false
threeDS2CardRangeDetails: [{
brandCode: "visa",
endRange: "411111111111",
startRange: "411111111111",
threeDS2Version: "2.1.0",
threeDSMethodURL: "https://pal-test.adyen.com/threeds2simulator/acs/startMethod.shtml"
}],
threeDS2supported: true
};
let client: Client;
let binLookupService: BinLookup;
let binLookup: BinLookup;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
binLookupService = new BinLookup(client);
client = createMockClientFromResponse();
binLookup = new BinLookup(client);
scope = nock(`${client.config.endpoint}${Client.BIN_LOOKUP_PAL_SUFFIX}${Client.BIN_LOOKUP_API_VERSION}`);
});
afterEach((): void => {
nock.cleanAll();
});
describe("Bin Lookup", function (): void {
test("should succeed on get 3ds availability", async function (): Promise<void> {
const threeDSAvailabilityRequest: binlookup.ThreeDSAvailabilityRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
it("should succeed on get 3ds availability", async function (): Promise<void> {
const threeDSAvailabilityRequest: IBinLookup.ThreeDSAvailabilityRequest = {
merchantAccount: "MOCK_MERCHANT_ACCOUNT",
brands: ["randomBrand"],
cardNumber: "4111111111111111"
};
@@ -42,12 +62,12 @@ describe("Bin Lookup", function (): void {
scope.post("/get3dsAvailability")
.reply(200, threeDSAvailabilitySuccess);
const response = await binLookupService.get3dsAvailability(threeDSAvailabilityRequest);
const response = await binLookup.get3dsAvailability(threeDSAvailabilityRequest);
expect(response).toEqual< binlookup.ThreeDSAvailabilityResponse>(threeDSAvailabilitySuccess);
expect(response).toEqual(threeDSAvailabilitySuccess);
});
test("should fail with invalid merchant", async function (): Promise<void> {
it("should fail with invalid merchant", async function (): Promise<void> {
const threeDSAvailabilityRequest: { [key: string]: undefined|string|[] } = {
merchantAccount: undefined,
cardNumber: "4111111111111",
@@ -58,52 +78,40 @@ describe("Bin Lookup", function (): void {
.reply(403, JSON.stringify({status: 403, message: "fail", errorCode: "171"}));
try {
await binLookupService.get3dsAvailability(threeDSAvailabilityRequest as unknown as binlookup.ThreeDSAvailabilityRequest);
await binLookup.get3dsAvailability(threeDSAvailabilityRequest as unknown as IBinLookup.ThreeDSAvailabilityRequest);
fail("Expected request to fail");
} catch (e) {
expect(e instanceof HttpClientException).toBeTruthy();
}
});
test("should succeed on get cost estimate", async function (): Promise<void> {
const expected = {
cardBin: {
bin: "",
fundsAvailability: "I",
issuingBank: "ADYEN TEST BANK",
issuingCountry: "NL",
paymentMethod: "visa",
payoutEligible: "Y",
summary: "",
},
costEstimateAmount: {
currency: "EUR",
value: 10
},
it("should succeed on get cost estimate", async function (): Promise<void> {
const response = {
cardBin: {summary: "1111"},
resultCode: "Unsupported",
surchargeType: "ZERO"
};
const costEstimateRequest: binlookup.CostEstimateRequest = {
const costEstimateRequest: IBinLookup.CostEstimateRequest = {
amount: { currency: "EUR", value: 1000 },
assumptions: {
assumeLevel3Data: true,
assume3DSecureAuthenticated: true
},
cardNumber: "411111111111",
merchantAccount: process.env.ADYEN_MERCHANT!,
merchantAccount: "MOCKED_MERCHANT_ACC",
merchantDetails: {
countryCode: "NL",
mcc: "7411",
enrolledIn3DSecure: true
},
shopperInteraction: binlookup.CostEstimateRequest.ShopperInteractionEnum.Ecommerce,
shopperInteraction: "Ecommerce"
};
scope.post("/getCostEstimate")
.reply(200, expected);
.reply(200, response);
const response = await binLookupService.getCostEstimate(costEstimateRequest);
const expected = await binLookup.getCostEstimate(costEstimateRequest);
expect(response).toEqual(expected);
});
});
});

View File

@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable @typescript-eslint/camelcase */
import checkServerIdentity from "../helpers/checkServerIdentity";
import { PeerCertificate } from "tls";
import {PeerCertificate} from "tls";
const createMockedCertificate = (CN: string): PeerCertificate => ({
subjectaltname: "Adyen B.V",
@@ -28,7 +29,6 @@ const createMockedCertificate = (CN: string): PeerCertificate => ({
valid_from: "Nov 19 15:03:32 2018 GMT",
valid_to: "Nov 11 15:03:32 2048 GMT",
fingerprint: "MOCKED_FINGERPRINT",
fingerprint256: "MOCKED_FINGERPRINT_256",
ext_key_usage: ["1.2.3.4.5.6.7.8"],
serialNumber: "1000",
raw: Buffer.from("test")

View File

@@ -1,45 +1,64 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen NodeJS API Library
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import nock from "nock";
import {createClient} from "../__mocks__/base";
import { createMockClientFromResponse } from "../__mocks__/base";
import {paymentMethodsSuccess} from "../__mocks__/checkout/paymentMethodsSuccess";
import {paymentsSuccess} from "../__mocks__/checkout/paymentsSuccess";
import {paymentDetailsSuccess} from "../__mocks__/checkout/paymentsDetailsSuccess";
import {paymentSessionSuccess} from "../__mocks__/checkout/paymentSessionSucess";
import {originKeysSuccess} from "../__mocks__/checkout/originkeysSuccess";
import {paymentsResultMultibancoSuccess} from "../__mocks__/checkout/paymentsResultMultibancoSuccess";
import {paymentsResultSuccess} from "../__mocks__/checkout/paymentsResultSucess";
import {sessionsSuccess} from "../__mocks__/checkout/sessionsSuccess";
import Client from "../client";
import Checkout from "../services/checkout";
import HttpClientException from "../httpClient/httpClientException";
import { checkout } from "../typings";
const merchantAccount = process.env.ADYEN_MERCHANT!;
const merchantAccount = "MagentoMerchantTest";
const reference = "Your order number";
function createAmountObject(currency: string, value: number): checkout.Amount {
function createAmountObject(currency: string, value: number): ICheckout.Amount {
return {
currency,
value,
};
}
function createPaymentsDetailsRequest(): checkout.DetailsRequest {
function createPaymentsDetailsRequest(): ICheckout.DetailsRequest {
return {
details: {
mD: "mdValue",
paRes: "paResValue",
MD: "mdValue",
PaRes: "paResValue",
},
paymentData: "Ab02b4c0!BQABAgCJN1wRZuGJmq8dMncmypvknj9s7l5Tj...",
};
}
export function createPaymentsCheckoutRequest(): checkout.PaymentRequest {
export function createPaymentsCheckoutRequest(): ICheckout.PaymentRequest {
const paymentMethodDetails = {
type: checkout.CardDetails.TypeEnum.Scheme,
encryptedCardNumber: "test_4111111111111111",
encryptedExpiryMonth: "test_03",
encryptedExpiryYear: "test_2030",
encryptedSecurityCode: "test_737"
cvc: "737",
expiryMonth: "10",
expiryYear: "2018",
holderName: "John Smith",
number: "4111111111111111",
type: "scheme",
};
return {
@@ -48,64 +67,10 @@ export function createPaymentsCheckoutRequest(): checkout.PaymentRequest {
paymentMethod: paymentMethodDetails,
reference,
returnUrl: "https://your-company.com/...",
shopperReference: "shopperReference",
storePaymentMethod: true
};
}
function createPaymentSessionRequest(): checkout.PaymentSetupRequest {
return {
amount: createAmountObject("USD", 1000),
countryCode: "NL",
merchantAccount,
reference,
returnUrl: "https://your-company.com/...",
channel: checkout.PaymentSetupRequest.ChannelEnum.Web,
sdkVersion: "3.7.0"
};
}
function getPaymentLinkSuccess(expiresAt: string): checkout.PaymentLinkResponse {
return {
amount: createAmountObject("USD", 1000),
expiresAt,
reference,
url: "PaymentLinkResponse.url",
id: "mocked_id",
merchantAccount,
status: checkout.PaymentLinkResponse.StatusEnum.Active
};
}
function createPaymentLinkRequest(): checkout.CreatePaymentLinkRequest {
return {
allowedPaymentMethods: ["scheme", "boletobancario"],
amount: createAmountObject("USD", 1000),
countryCode: "BR",
merchantAccount,
shopperReference: "shopperReference",
shopperEmail: "test@email.com",
shopperLocale: "pt_BR",
billingAddress: {
street: "Roque Petroni Jr",
postalCode: "59000060",
city: "São Paulo",
houseNumberOrName: "999",
country: "BR",
stateOrProvince: "SP"
},
deliveryAddress: {
street: "Roque Petroni Jr",
postalCode: "59000060",
city: "São Paulo",
houseNumberOrName: "999",
country: "BR",
stateOrProvince: "SP"
},
reference
};
}
function createSessionRequest(): checkout.CreateCheckoutSessionRequest {
function createPaymentSessionRequest(): ICheckout.PaymentSetupRequest {
return {
amount: createAmountObject("USD", 1000),
countryCode: "NL",
@@ -116,362 +81,146 @@ function createSessionRequest(): checkout.CreateCheckoutSessionRequest {
}
let client: Client;
let checkoutService: Checkout;
let checkout: Checkout;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
client = createMockClientFromResponse();
scope = nock(`${client.config.checkoutEndpoint}/${Client.CHECKOUT_API_VERSION}`);
checkoutService = new Checkout(client);
});
afterEach(() => {
nock.cleanAll();
checkout = new Checkout(client);
});
describe("Checkout", (): void => {
test("should add idempotency key to request headers", async (): Promise<void> => {
const paymentsRequest: checkout.PaymentRequest = createPaymentsCheckoutRequest();
scope.post("/payments")
.reply(200, paymentsSuccess)
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.payments(paymentsRequest, {idempotencyKey: "testKey"});
const paymentMethodsRequest: checkout.PaymentMethodsRequest = {merchantAccount};
scope.post("/paymentMethods")
.reply(200, paymentMethodsSuccess)
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.paymentMethods(paymentMethodsRequest, {idempotencyKey: "testKey"});
const expiresAt = "2019-12-17T10:05:29Z";
const paymentLinkSuccess: checkout.PaymentLinkResponse = getPaymentLinkSuccess(expiresAt);
scope.post("/paymentLinks")
.reply(200, paymentLinkSuccess)
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.paymentLinks(createPaymentLinkRequest(), {idempotencyKey: "testKey"});
scope.patch("/paymentLinks/321")
.reply(200, { ...paymentLinkSuccess, status: "expired" })
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.updatePaymentLinks("321", "expired", {idempotencyKey: "testKey"});
scope.get("/paymentLinks/123")
.reply(200, paymentLinkSuccess)
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.getPaymentLinks("123", {idempotencyKey: "testKey"});
scope.post("/payments/details")
.reply(200, paymentDetailsSuccess)
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.paymentsDetails(createPaymentsDetailsRequest(), {idempotencyKey: "testKey"});
scope.post("/paymentSession")
.reply(200, paymentSessionSuccess)
.matchHeader("Idempotency-Key", "testKey");
const paymentSessionRequest: checkout.PaymentSetupRequest = createPaymentSessionRequest();
await checkoutService.paymentSession(paymentSessionRequest, {idempotencyKey: "testKey"});
scope.post("/payments/result")
.reply(200, paymentsResultSuccess)
.matchHeader("Idempotency-Key", "testKey");
const paymentResultRequest: checkout.PaymentVerificationRequest = {
payload: "This is a test payload",
};
await checkoutService.paymentResult(paymentResultRequest, {idempotencyKey: "testKey"});
const orderRequest: checkout.CheckoutCreateOrderRequest = {
amount: createAmountObject("USD", 1000),
merchantAccount,
reference
};
scope.post("/orders")
.reply(200, {})
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.orders(orderRequest, {idempotencyKey: "testKey"});
scope.post("/orders/cancel")
.reply(200, {})
.matchHeader("Idempotency-Key", "testKey");
await checkoutService.ordersCancel({
order: {
orderData: "mock_data",
pspReference: "mock_pspref"
},
merchantAccount
}, {idempotencyKey: "testKey"});
scope.post("/sessions")
.reply(200, sessionsSuccess)
.matchHeader("Idempotency-Key", "testKey");
const sessionsRequest: checkout.CreateCheckoutSessionRequest = createSessionRequest();
await checkoutService.sessions(sessionsRequest, {idempotencyKey: "testKey"});
});
test("should make a payment.", async (): Promise<void> => {
it("should make a payment", async (): Promise<void> => {
scope.post("/payments")
.reply(200, paymentsSuccess);
const paymentsRequest: checkout.PaymentRequest = createPaymentsCheckoutRequest();
const paymentsResponse: checkout.PaymentResponse = await checkoutService.payments(paymentsRequest);
expect(paymentsResponse.pspReference).toBeTruthy();
const paymentsRequest: ICheckout.PaymentRequest = createPaymentsCheckoutRequest();
const paymentsResponse: ICheckout.PaymentResponse = await checkout.payments(paymentsRequest);
expect(paymentsResponse.pspReference).toEqual("8535296650153317");
});
test("Should properly handle error responses from API", async (): Promise<void> => {
it("should return correct Exception", async (): Promise<void> => {
try {
scope.post("/payments")
.reply(422, {
"status": 422,
"errorCode": "200",
"message": "Field 'countryCode' is not valid.",
"errorType": "validation",
"pspReference": "DMB552CV6JHKGK82",
});
.reply(401);
const paymentsRequest: checkout.PaymentRequest = createPaymentsCheckoutRequest();
await checkoutService.payments(paymentsRequest);
fail("No exception was thrown");
} catch (error) {
expect(error instanceof HttpClientException).toBeTruthy();
if(error instanceof HttpClientException && error.responseBody) {
expect(JSON.parse(error.responseBody).errorType).toBe("validation");
} else {
fail("Error did not contain the expected data");
}
const paymentsRequest: ICheckout.PaymentRequest = createPaymentsCheckoutRequest();
await checkout.payments(paymentsRequest);
} catch (e) {
expect(e instanceof HttpClientException).toBeTruthy();
}
});
test("should have valid payment methods", async (): Promise<void> => {
const paymentMethodsRequest: checkout.PaymentMethodsRequest = {merchantAccount};
it("should have valid payment methods", async (): Promise<void> => {
const paymentMethodsRequest: ICheckout.PaymentMethodsRequest = {merchantAccount: "MagentoMerchantTest"};
scope.post("/paymentMethods")
.reply(200, paymentMethodsSuccess);
const paymentMethodsResponse = await checkoutService.paymentMethods(paymentMethodsRequest);
const paymentMethodsResponse = await checkout.paymentMethods(paymentMethodsRequest);
if (paymentMethodsResponse && paymentMethodsResponse.paymentMethods) {
expect(paymentMethodsResponse.paymentMethods.length).toBeGreaterThan(0);
expect(paymentMethodsResponse.paymentMethods.length).toEqual(65);
expect(paymentMethodsResponse.paymentMethods[0].name).toEqual("AliPay");
} else {
fail();
}
});
test("should have valid payment link", async (): Promise<void> => {
it("should have valid payment link", async (): Promise<void> => {
const amount = createAmountObject("BRL", 1000);
const expiresAt = "2019-12-17T10:05:29Z";
const paymentLinkSuccess: checkout.PaymentLinkResponse = getPaymentLinkSuccess(expiresAt);
const paymentLinkRequest: ICheckout.CreatePaymentLinkRequest = {
allowedPaymentMethods: ["scheme", "boletobancario"],
amount,
countryCode: "BR",
merchantAccount,
shopperReference: "shopperReference",
shopperEmail: "test@email.com",
shopperLocale: "pt_BR",
billingAddress: {
street: "Roque Petroni Jr",
postalCode: "59000060",
city: "São Paulo",
houseNumberOrName: "999",
country: "BR",
stateOrProvince: "SP"
},
deliveryAddress: {
street: "Roque Petroni Jr",
postalCode: "59000060",
city: "São Paulo",
houseNumberOrName: "999",
country: "BR",
stateOrProvince: "SP"
},
expiresAt,
reference
};
const paymentLinkSuccess: ICheckout.CreatePaymentLinkResponse = {
amount,
expiresAt,
reference,
url: "paymentLinkResponse.url"
};
scope.post("/paymentLinks").reply(200, paymentLinkSuccess);
const paymentSuccessLinkResponse = await checkoutService.paymentLinks(createPaymentLinkRequest());
expect(paymentSuccessLinkResponse).toBeTruthy();
const paymentSuccessLinkResponse = await checkout.paymentLinks(paymentLinkRequest);
expect(paymentLinkSuccess).toEqual(paymentSuccessLinkResponse);
});
test("should get payment link", async (): Promise<void> => {
const expiresAt = "2019-12-17T10:05:29Z";
const paymentLinkSuccess: checkout.PaymentLinkResponse = getPaymentLinkSuccess(expiresAt);
scope.post("/paymentLinks").reply(200, paymentLinkSuccess);
const paymentSuccessLinkResponse = await checkoutService.paymentLinks(createPaymentLinkRequest());
scope.get(`/paymentLinks/${paymentSuccessLinkResponse.id}`).reply(200, paymentLinkSuccess);
const paymentLink = await checkoutService.getPaymentLinks(paymentSuccessLinkResponse.id);
expect(paymentLink).toBeTruthy();
});
test("should patch payment link", async (): Promise<void> => {
const expiresAt = "2019-12-17T10:05:29Z";
const paymentLinkSuccess: checkout.PaymentLinkResponse = getPaymentLinkSuccess(expiresAt);
scope.post("/paymentLinks").reply(200, paymentLinkSuccess);
const paymentSuccessLinkResponse = await checkoutService.paymentLinks(createPaymentLinkRequest());
scope.patch(`/paymentLinks/${paymentSuccessLinkResponse.id}`).reply(200, { ...paymentLinkSuccess, status: "expired" });
const paymentLink = await checkoutService.updatePaymentLinks(paymentSuccessLinkResponse.id, "expired");
expect(paymentLink.status).toEqual("expired");
});
test("should have payment details", async (): Promise<void> => {
it("should have payment details", async (): Promise<void> => {
scope.post("/payments/details")
.reply(200, paymentDetailsSuccess);
const paymentsResponse = await checkoutService.paymentsDetails(createPaymentsDetailsRequest());
const paymentsResponse = await checkout.paymentsDetails(createPaymentsDetailsRequest());
expect(paymentsResponse.resultCode).toEqual("Authorised");
});
test("should have payment session success", async (): Promise<void> => {
it("should have payment session success", async (): Promise<void> => {
scope.post("/paymentSession")
.reply(200, paymentSessionSuccess);
const paymentSessionRequest: checkout.PaymentSetupRequest = createPaymentSessionRequest();
const paymentSessionResponse = await checkoutService.paymentSession(paymentSessionRequest);
const paymentSessionRequest: ICheckout.PaymentSetupRequest = createPaymentSessionRequest();
const paymentSessionResponse = await checkout.paymentSession(paymentSessionRequest);
expect(paymentSessionResponse.paymentSession).not.toBeUndefined();
});
test("should have payments result", async (): Promise<void> => {
it("should have payments result", async (): Promise<void> => {
scope.post("/payments/result")
.reply(200, paymentsResultSuccess);
const paymentResultRequest: checkout.PaymentVerificationRequest = {
const paymentResultRequest: ICheckout.PaymentVerificationRequest = {
payload: "This is a test payload",
};
const paymentResultResponse = await checkoutService.paymentResult(paymentResultRequest);
const paymentResultResponse = await checkout.paymentResult(paymentResultRequest);
expect(paymentResultResponse.resultCode).toEqual("Authorised");
});
test("should have missing identifier on live", async (): Promise<void> => {
it("should have missing identifier on live", async (): Promise<void> => {
client.setEnvironment("LIVE");
try {
new Checkout(client);
fail();
} catch (e) {
if(e instanceof Error) {
expect(e.message).toEqual("Please provide your unique live url prefix on the setEnvironment() call on the Client or provide checkoutEndpoint in your config object.");
} else {
fail();
}
expect(e.message).toEqual("Please provide your unique live url prefix on the setEnvironment() call on the Client or provide checkoutEndpoint in your config object.");
}
});
test("should succeed on multibanco payment", async (): Promise<void> => {
it("should succeed on multibanco payment", async (): Promise<void> => {
scope.post("/payments")
.reply(200, paymentsResultMultibancoSuccess);
const paymentsRequest: checkout.PaymentRequest = createPaymentsCheckoutRequest();
const paymentsResponse: checkout.PaymentResponse = await checkoutService.payments(paymentsRequest);
const paymentsRequest: ICheckout.PaymentRequest = createPaymentsCheckoutRequest();
const paymentsResponse: ICheckout.PaymentResponse = await checkout.payments(paymentsRequest);
expect(paymentsResponse.pspReference).toEqual("8111111111111111");
expect(paymentsResponse.pspReference).toBeTruthy();
expect(paymentsResponse.additionalData).toBeTruthy();
});
test("should get origin keys", async (): Promise<void> => {
const checkoutUtility = new Checkout(client);
const originKeysRequest: checkout.CheckoutUtilityRequest = {
originDomains: ["https://www.your-domain.com"],
};
nock(`${client.config.checkoutEndpoint}`)
.post(`/${Client.CHECKOUT_API_VERSION}/originKeys`)
.reply(200, originKeysSuccess);
const originKeysResponse = await checkoutUtility.originKeys(originKeysRequest);
if (originKeysResponse.originKeys) {
return expect(originKeysResponse.originKeys["https://www.your-domain.com"].startsWith("pub.v2")).toBeTruthy();
if (paymentsResponse.additionalData) {
expect(paymentsResponse.additionalData["comprafacil.amount"]).toEqual("101.01");
expect(paymentsResponse.additionalData["comprafacil.deadline"]).toEqual("3");
expect(paymentsResponse.additionalData["comprafacil.entity"]).toEqual("12345");
}
fail("Error: originKeysResponse.originKeys is empty");
});
// TODO: add gift card to PaymentMethod and unmock test
test("should get payment methods balance", async (): Promise<void> => {
const paymentMethodsRequest: checkout.CheckoutBalanceCheckRequest = {
merchantAccount,
amount: createAmountObject("USD", 1000),
paymentMethod: { },
reference: "mocked_reference"
};
const paymentMethodsBalanceResponse: checkout.CheckoutBalanceCheckResponse = {
balance: {currency: "USD", value: 1000},
resultCode: checkout.CheckoutBalanceCheckResponse.ResultCodeEnum.Success
};
scope.post("/paymentMethods/balance")
.reply(200, paymentMethodsBalanceResponse);
const paymentsResponse: checkout.CheckoutBalanceCheckResponse = await checkoutService.paymentMethodsBalance(paymentMethodsRequest);
expect(paymentsResponse.balance.value).toEqual(1000);
});
test("should create order", async (): Promise<void> => {
const expiresAt = "2019-12-17T10:05:29Z";
const orderRequest: checkout.CheckoutCreateOrderRequest = {
amount: createAmountObject("USD", 1000),
merchantAccount,
reference
};
const orderResponse: checkout.CheckoutCreateOrderResponse = {
expiresAt,
amount: createAmountObject("USD", 500),
orderData: "mocked_order_data",
remainingAmount: {currency: "USD", value: 500} ,
resultCode: checkout.CheckoutCreateOrderResponse.ResultCodeEnum.Success
};
scope.post("/orders")
.reply(200, orderResponse);
const response: checkout.CheckoutCreateOrderResponse = await checkoutService.orders(orderRequest);
expect(response).toBeTruthy();
});
test("should cancel order", async (): Promise<void> => {
const expiresAt = "2019-12-17T10:05:29Z";
const orderRequest: checkout.CheckoutCreateOrderRequest = {
amount: createAmountObject("USD", 1000),
merchantAccount,
reference
};
const orderResponse: checkout.CheckoutCreateOrderResponse = {
expiresAt,
amount: createAmountObject("USD", 500),
orderData: "mocked_order_data",
remainingAmount: {currency: "USD", value: 500},
resultCode: checkout.CheckoutCreateOrderResponse.ResultCodeEnum.Success
};
scope.post("/orders")
.reply(200, orderResponse);
const createOrderResponse: checkout.CheckoutCreateOrderResponse = await checkoutService.orders(orderRequest);
const orderCancelResponse: checkout.CheckoutCancelOrderResponse = {
pspReference: "mocked_psp_ref",
resultCode: checkout.CheckoutCancelOrderResponse.ResultCodeEnum.Received
};
scope.post("/orders/cancel")
.reply(200, orderCancelResponse);
const response: checkout.CheckoutCancelOrderResponse = await checkoutService.ordersCancel({
order: {
orderData: createOrderResponse.orderData,
pspReference: createOrderResponse.pspReference!
},
merchantAccount
});
expect(response).toBeTruthy();
});
test("should create a session.", async (): Promise<void> => {
scope.post("/sessions")
.reply(200, sessionsSuccess);
const sessionsRequest: checkout.CreateCheckoutSessionRequest = createSessionRequest();
const sessionsResponse: checkout.CreateCheckoutSessionResponse = await checkoutService.sessions(sessionsRequest);
expect(sessionsResponse.sessionData).toBeTruthy();
expect(sessionsResponse.expiresAt).toBeInstanceOf(Date);
expect(sessionsResponse.expiresAt.getFullYear()).toBeGreaterThan(0);
});
test("Should get card details", async (): Promise<void> => {
scope.post("/cardDetails")
.reply(200, {
"brands": [
{
"supported": true,
"type": "visa"
}
]
});
const cardDetailsRequest: checkout.CardDetailsRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"cardNumber": "411111"
};
const cardDetailsReponse: checkout.CardDetailsResponse = await checkoutService.cardDetails(cardDetailsRequest);
expect(cardDetailsReponse?.brands?.length).toBe(1);
});
});

View File

@@ -0,0 +1,47 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen NodeJS API Library
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import nock from "nock";
import { createMockClientFromResponse } from "../__mocks__/base";
import {originKeysSuccess} from "../__mocks__/checkoutUtility/originkeysSuccess";
import CheckoutUtility from "../services/checkoutUtility";
import Client from "../client";
describe("Checkout Utility", (): void => {
it("should get origin keys", async (): Promise<void> => {
const client = createMockClientFromResponse();
const checkoutUtility = new CheckoutUtility(client);
const originKeysRequest: ICheckoutUtility.CheckoutUtilityRequest = {
originDomains: ["www.test.com", "https://www.your-domain2.com"],
};
nock(`${client.config.checkoutEndpoint}`)
.post(`/${Client.CHECKOUT_UTILITY_API_VERSION}/originKeys`)
.reply(200, originKeysSuccess);
const originKeysResponse = await checkoutUtility.originKeys(originKeysRequest);
if (originKeysResponse.originKeys) {
return expect(originKeysResponse.originKeys["https://www.your-domain1.com"])
.toEqual("pub.v2.7814286629520534.aHR0cHM6Ly93d3cueW91ci1kb21haW4xLmNvbQ.UEwIBmW9-c_uXo5wSEr2w8Hz8hVIpujXPHjpcEse3xI");
}
fail("Error: originKeysResponse.originKeys is empty");
});
});

View File

@@ -1,293 +0,0 @@
import nock from "nock";
import {createClient} from "../__mocks__/base";
import Client from "../client";
import ClassicIntegration from "../services/classicIntegration";
import { payments } from "../typings";
let client: Client;
let classicIntegration: ClassicIntegration;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.paymentEndpoint}/${Client.PAYMENT_API_VERSION}`);
classicIntegration = new ClassicIntegration(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("Classic Integration", (): void => {
test("Should authorise payment", async (): Promise<void> => {
scope.post("/authorise")
.reply(200, {
"additionalData": {
"scaExemptionRequested": "transactionRiskAnalysis",
"checkout.cardAddedBrand": "visa"
},
"pspReference": "JVBXGSDM53RZNN82",
"resultCode": "Authorised",
"authCode": "011381"
}
);
const paymentRequest: payments.PaymentRequest = {
"card": {
"number": "4111111111111111",
"expiryMonth": "03",
"expiryYear": "2030",
"cvc": "737",
"holderName": "John Smith"
},
"amount": {
"value": 1500,
"currency": "EUR"
},
"reference": "YOUR_REFERENCE",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const paymentResult: payments.PaymentResult = await classicIntegration.authorise(paymentRequest);
expect(paymentResult.pspReference).toEqual("JVBXGSDM53RZNN82");
});
test("Should complete 3DS authorisation", async (): Promise<void> => {
scope.post("/authorise3d")
.reply(200, {
"additionalData": {
"scaExemptionRequested": "transactionRiskAnalysis",
"checkout.cardAddedBrand": "visa"
},
"pspReference": "JVBXGSDM53RZNN82",
"resultCode": "Authorised",
"authCode": "011381"
}
);
const paymentRequest: payments.PaymentRequest3d = {
"md": "31h..........vOXek7w",
"paResponse": "eNqtmF........wGVA4Ch",
"shopperIP": "61.294.12.12",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const paymentResult: payments.PaymentResult = await classicIntegration.authorise3d(paymentRequest);
expect(paymentResult.pspReference).toEqual("JVBXGSDM53RZNN82");
});
test("Should complete 3DS2 authorisation", async (): Promise<void> => {
scope.post("/authorise3ds2")
.reply(200, {
"additionalData": {
"scaExemptionRequested": "transactionRiskAnalysis",
"checkout.cardAddedBrand": "visa"
},
"pspReference": "JVBXGSDM53RZNN82",
"resultCode": "Authorised",
"authCode": "011381"
}
);
const paymentRequest: payments.PaymentRequest3ds2 = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"amount": {
"value": 1500,
"currency": "EUR"
},
"reference": "YOUR_REFERENCE",
"threeDS2RequestData": {
"threeDSCompInd": "Y",
"deviceChannel": "testDeviceChannel"
},
"threeDS2Token": "— - BINARY DATA - -"
};
const paymentResult: payments.PaymentResult = await classicIntegration.authorise3ds2(paymentRequest);
expect(paymentResult.pspReference).toEqual("JVBXGSDM53RZNN82");
});
test("Should get auth result after 3DS authentication", async (): Promise<void> => {
scope.post("/getAuthenticationResult").reply(200, {
"threeDS2Result": { "authenticationValue": "THREEDS2RESULT"}
});
const getAuthenticationResultrequest: payments.AuthenticationResultRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"pspReference": "9935272408535455"
};
const getAuthenticationResultResponse: payments.AuthenticationResultResponse = await classicIntegration.getAuthenticationResult(getAuthenticationResultrequest);
expect(getAuthenticationResultResponse?.threeDS2Result?.authenticationValue).toEqual("THREEDS2RESULT");
});
test("Should retrieve 3DS2 result", async (): Promise<void> => {
scope.post("/retrieve3ds2Result").reply(200, {
"threeDS2Result": { "authenticationValue": "THREEDS2RESULT"}
});
const retrieve3ds2ResultRequest: payments.ThreeDS2ResultRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"pspReference": "9935272408535455"
};
const retrieve3ds2ResultResponse: payments.ThreeDS2ResultResponse = await classicIntegration.retrieve3ds2Result(retrieve3ds2ResultRequest);
expect(retrieve3ds2ResultResponse?.threeDS2Result?.authenticationValue).toEqual("THREEDS2RESULT");
});
test("Should succesfully send Capture request", async (): Promise<void> => {
scope.post("/capture")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[capture-received]"
});
const modificationRequest: payments.CaptureRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"modificationAmount": {
"value": 500,
"currency": "EUR"
},
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.capture(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.CaptureReceived);
});
test("Should succesfully send Cancel request", async (): Promise<void> => {
scope.post("/cancel")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[cancel-received]"
});
const modificationRequest: payments.CancelRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.cancel(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.CancelReceived);
});
test("Should succesfully send Refund request", async (): Promise<void> => {
scope.post("/refund")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[refund-received]"
});
const modificationRequest: payments.RefundRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"modificationAmount": {
"value": 500,
"currency": "EUR"
},
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.refund(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.RefundReceived);
});
test("Should succesfully send CancelOrRefund request", async (): Promise<void> => {
scope.post("/cancelOrRefund")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[cancelOrRefund-received]"
});
const modificationRequest: payments.CancelOrRefundRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.cancelOrRefund(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.CancelOrRefundReceived);
});
test("Should succesfully send TechnicalCancel request", async (): Promise<void> => {
scope.post("/technicalCancel")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[technical-cancel-received]"
});
const modificationRequest: payments.TechnicalCancelRequest = {
"originalMerchantReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"modificationAmount": {
"value": 500,
"currency": "EUR"
},
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.technicalCancel(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.TechnicalCancelReceived);
});
test("Should succesfully send AdjustAuthorisation request", async (): Promise<void> => {
scope.post("/adjustAuthorisation")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[adjustAuthorisation-received]"
});
const modificationRequest: payments.AdjustAuthorisationRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"modificationAmount": {
"value": 500,
"currency": "EUR"
},
"reference": "YourModificationReference",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.adjustAuthorisation(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.AdjustAuthorisationReceived);
});
test("Should succesfully send Donate request", async (): Promise<void> => {
scope.post("/donate")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[donation-received]"
});
const modificationRequest: payments.DonationRequest = {
"originalReference": "COPY_PSP_REFERENCE_FROM_AUTHORISE_RESPONSE",
"modificationAmount": {
"value": 500,
"currency": "EUR"
},
"reference": "YOUR_DONATION_REFERENCE",
"donationAccount": "AdyenGivingDemo",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT"
};
const modificationResult: payments.ModificationResult = await classicIntegration.donate(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.DonationReceived);
});
test("Should succesfully send VoidPendingRefund request", async (): Promise<void> => {
scope.post("/voidPendingRefund")
.reply(200, {
"pspReference": "YOUR_REFERENCE",
"response": "[voidPendingRefund-received]"
});
const modificationRequest: payments.VoidPendingRefundRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"tenderReference": "5Iw8001176969533005",
"uniqueTerminalId": "VX820-123456789"
};
const modificationResult: payments.ModificationResult = await classicIntegration.voidPendingRefund(modificationRequest);
expect(modificationResult.response).toEqual(payments.ModificationResult.ResponseEnum.VoidPendingRefundReceived);
});
});

View File

@@ -1,11 +0,0 @@
import Client from "../client";
describe("API Client", function (): void {
test("should be able to make a request using basic auth", async function (): Promise<void> {
new Client({
username: process.env.ADYEN_USER!,
password: process.env.ADYEN_PASSWORD!,
environment: "TEST"
});
});
});

View File

@@ -1,59 +0,0 @@
import nock from "nock";
import { createClient } from "../__mocks__/base";
import { DataProtection } from "../services";
import Client from "../client";
import HttpClientException from "../httpClient/httpClientException";
import { dataProtection } from "../typings";
let client: Client,
dataProtectionService: DataProtection,
scope: nock.Scope;
beforeEach((): void => {
if(!nock.isActive()) {
nock.activate();
}
client = createClient();
dataProtectionService = new DataProtection(client);
scope = nock(`${client.config.dataProtectionEndpoint}/${Client.DATA_PROTECTION_API_VERSION}`);
});
afterEach(() => {
nock.cleanAll();
});
describe("DataProtection", (): void => {
test("should make succesful subjectErasure call", async (): Promise<void> => {
const requestSubjectErasureSuccess: dataProtection.SubjectErasureResponse = {
"result": dataProtection.SubjectErasureResponse.ResultEnum.Success,
};
const requestSubjectErasureRequest: dataProtection.SubjectErasureByPspReferenceRequest = {
"merchantAccount": "MY_MERCHANT_ACCOUNT",
"forceErasure": true,
"pspReference": "0123456789"
};
scope.post("/requestSubjectErasure")
.reply(200, requestSubjectErasureSuccess);
const response: dataProtection.SubjectErasureResponse = await dataProtectionService.requestSubjectErasure(requestSubjectErasureRequest);
expect(response.result).toEqual(dataProtection.SubjectErasureResponse.ResultEnum.Success);
});
test("should return correct Exception", async (): Promise<void> => {
try {
scope.post("/requestSubjectErasure")
.reply(401);
const requestSubjectErasureRequest: dataProtection.SubjectErasureByPspReferenceRequest = {
"merchantAccount": "MY_MERCHANT_ACCOUNT",
"forceErasure": true,
"pspReference": "0123456789"
};
await dataProtectionService.requestSubjectErasure(requestSubjectErasureRequest);
} catch (e) {
expect(e instanceof HttpClientException).toBeTruthy();
}
});
});

View File

@@ -1,30 +1,22 @@
import HmacValidator from "../utils/hmacValidator";
import { AdditionalData, NotificationItem, NotificationRequestItem } from "../typings/notification/models";
import { ApiConstants } from "../constants/apiConstants";
import NotificationRequest from "../notification/notificationRequest";
import {NotificationRequestItem} from "../typings/notification";
import {ApiConstants} from "../constants/apiConstants";
const key = "DFB1EB5485895CFA84146406857104ABB4CBCABDC8AAF103A624C8F6A3EAAB00";
const expectedSign = "ZNBPtI+oDyyRrLyD1XirkKnQgIAlFc07Vj27TeHsDRE=";
const notificationRequestItem: { NotificationRequestItem: NotificationRequestItem } = {
NotificationRequestItem : {
pspReference: "pspReference",
originalReference: "originalReference",
merchantAccountCode: "merchantAccount",
merchantReference: "reference",
amount: {currency: "EUR", value: 1000},
eventCode: NotificationRequestItem.EventCodeEnum.ReportAvailable,
eventDate: "2019-09-21T11:45:24.637Z",
paymentMethod: "VISA",
reason: "reason",
success: NotificationRequestItem.SuccessEnum.True,
additionalData: { [ApiConstants.HMAC_SIGNATURE]: expectedSign },
}
const expectedSign = "ipnxGCaUZ4l8TUW75a71/ghd2Fe5ffvX0pV4TLTntIc=";
const notificationRequestItem: NotificationRequestItem = {
pspReference: "pspReference",
originalReference: "originalReference",
merchantAccountCode: "merchantAccount",
merchantReference: "reference",
amount: {currency: "EUR", value: 1000},
eventCode: "EVENT",
eventDate: new Date("01-01-1970"),
paymentMethod: "VISA",
reason: "reason",
success: "true",
additionalData: { [ApiConstants.HMAC_SIGNATURE]: expectedSign },
};
const notification = new NotificationRequest({
live: "false",
notificationItems: [notificationRequestItem as unknown as NotificationItem]
});
describe("HMAC Validator", function (): void {
let hmacValidator: HmacValidator;
@@ -46,85 +38,22 @@ describe("HMAC Validator", function (): void {
expect(encrypted).toEqual("34oR8T1whkQWTv9P+SzKyp8zhusf9n0dpqrm9nsqSJs=");
});
it("should get correct data to sign", function (): void {
const data = hmacValidator.getDataToSign(notification.notificationItems![0]);
expect(data).toEqual("pspReference:originalReference:merchantAccount:reference:1000:EUR:REPORT_AVAILABLE:true");
const data = hmacValidator.getDataToSign(notificationRequestItem);
expect(data).toEqual("pspReference:originalReference:merchantAccount:reference:1000:EUR:EVENT:true");
});
it("should have valid hmac", function (): void {
const encrypted = hmacValidator.calculateHmac(notification.notificationItems![0], key);
const encrypted = hmacValidator.calculateHmac(notificationRequestItem, key);
expect(expectedSign).toEqual(encrypted);
expect(hmacValidator.validateHMAC(notification.notificationItems![0], key)).toBeTruthy();
expect(hmacValidator.validateHMAC(notificationRequestItem, key)).toBeTruthy();
});
it("should have invalid hmac", function (): void {
const invalidNotification = {
...notification.notificationItems![0],
additionalData: { [ApiConstants.HMAC_SIGNATURE as keyof AdditionalData]: "notValidSign" }
...notificationRequestItem,
additionalData: { [ApiConstants.HMAC_SIGNATURE]: "notValidSign" }
};
const result = hmacValidator.validateHMAC(invalidNotification, key);
expect(result).toBeFalsy();
});
it("should throw error with missing hmac signature", function(): void {
expect.assertions(1);
const notificationRequestItemNoAdditionalData: NotificationRequestItem = {
pspReference: "pspReference",
originalReference: "originalReference",
merchantAccountCode: "merchantAccount",
merchantReference: "reference",
amount: {currency: "EUR", value: 1000},
eventCode: NotificationRequestItem.EventCodeEnum.ReportAvailable,
eventDate: "2019-09-21T11:45:24.637Z",
paymentMethod: "VISA",
reason: "reason",
success: NotificationRequestItem.SuccessEnum.True,
additionalData: { },
};
try {
hmacValidator.validateHMAC(notificationRequestItemNoAdditionalData, key);
} catch(error) {
if(error instanceof Error) {
expect(error.message).toEqual(`Missing ${ApiConstants.HMAC_SIGNATURE}`);
} else {
fail();
}
}
});
it("should test hmac", function () {
const data = "countryCode:currencyCode:merchantAccount:merchantReference:paymentAmount:sessionValidity:skinCode:NL:EUR:MagentoMerchantTest2:TEST-PAYMENT-2017-02-01-14\\:02\\:05:199:2017-02-02T14\\:02\\:05+01\\:00:PKz2KML1";
const key = "DFB1EB5485895CFA84146406857104ABB4CBCABDC8AAF103A624C8F6A3EAAB00";
const hmacValidator = new HmacValidator();
const encrypted = hmacValidator.calculateHmac(data, key);
expect(encrypted).toEqual("34oR8T1whkQWTv9P+SzKyp8zhusf9n0dpqrm9nsqSJs=");
});
it("should validate HMAC", function () {
expect(hmacValidator.validateHMAC(notification.notificationItems![0], key)).toBeTruthy();
});
it("should have valid notification request item HMAC", function () {
const expectedSign = "ipnxGCaUZ4l8TUW75a71/ghd2Fe5ffvX0pV4TLTntIc=";
const notificationRequestItem = { NotificationRequestItem: {
pspReference: "pspReference",
originalReference: "originalReference",
merchantAccountCode: "merchantAccount",
merchantReference: "reference",
amount: { currency: "EUR", value: 1000 },
eventCode: "EVENT",
success: "true",
additionalData: { [ApiConstants.HMAC_SIGNATURE]: expectedSign }
}} as unknown as NotificationItem;
const notification = new NotificationRequest({
live: "false",
notificationItems: [notificationRequestItem]
});
const data = hmacValidator.getDataToSign(notification.notificationItems![0]);
expect("pspReference:originalReference:merchantAccount:reference:1000:EUR:EVENT:true").toEqual(data);
const encrypted = hmacValidator.calculateHmac(notification.notificationItems![0], key);
expect(expectedSign).toEqual(encrypted);
expect(hmacValidator.validateHMAC(notification.notificationItems![0], key)).toBeTruthy();
notification.notificationItems![0].additionalData![ApiConstants.HMAC_SIGNATURE] = "notValidSign";
expect(hmacValidator.validateHMAC(notification.notificationItems![0], key)).toBeFalsy();
});
});

View File

@@ -1,8 +1,8 @@
import nock, { Interceptor } from "nock";
import nock, {Interceptor} from "nock";
import Client from "../client";
import Checkout from "../services/checkout";
import ApiException from "../services/exception/apiException";
import { createPaymentsCheckoutRequest } from "./checkout.spec";
import {createPaymentsCheckoutRequest} from "./checkout.spec";
import HttpClientException from "../httpClient/httpClientException";
beforeEach((): void => {
@@ -12,7 +12,7 @@ beforeEach((): void => {
type errorType = "HttpClientException" | "ApiException";
type testOptions = { errorType: errorType; errorMessageContains?: string; errorMessageEquals?: string };
const getResponse = async ({apiKey , environment }: { apiKey: string; environment: Environment}, cb: (scope: Interceptor) => testOptions): Promise<void> => {
const getResponse = async ({apiKey , environment }: { apiKey: string; environment: Environment}, cb: (scope: Interceptor) => testOptions) => {
const client = new Client({ apiKey, environment });
const checkout = new Checkout(client);
@@ -25,19 +25,15 @@ const getResponse = async ({apiKey , environment }: { apiKey: string; environmen
await checkout.payments(createPaymentsCheckoutRequest());
fail("request should fail");
} catch (e) {
if(e instanceof ErrorException){
if (errorMessageEquals) expect(e.message).toEqual(errorMessageEquals);
if (errorMessageContains) expect(e.message.toLowerCase()).toContain(errorMessageContains);
} else {
fail();
}
expect(e instanceof ErrorException).toBeTruthy();
if(errorMessageEquals) expect(e.message).toEqual(errorMessageEquals);
if(errorMessageContains) expect(e.message.toLowerCase()).toContain(errorMessageContains);
}
};
describe("HTTP Client", function (): void {
it.each`
apiKey | environment | withError | args | errorType | contains | equals
apiKey | environment | withError | args | errorType | contains | equals
${""} | ${"TEST"} | ${true} | ${["mocked_error_response"]} | ${"ApiException"} | ${"x-api-key"} | ${""}
${"MOCKED_API_KEY"} | ${"TEST"} | ${true} | ${["some_error"]} | ${"ApiException"} | ${""} | ${"some_error"}
${"API_KEY"} | ${"TEST"} | ${false} | ${[401, { status: 401, message: "Invalid Request", errorCode: "171", errorType: "validationError"}]} | ${"HttpClientException"} | ${""} | ${"HTTP Exception: 401. null: Invalid Request"}
@@ -51,4 +47,4 @@ describe("HTTP Client", function (): void {
return { errorType, errorMessageContains: contains, errorMessageEquals: equals };
});
});
});
});

View File

@@ -1,326 +0,0 @@
import nock from "nock";
import Client from "../client";
import {createClient} from "../__mocks__/base";
import * as models from "../typings/legalEntityManagement/models";
import {Document, LegalEntityInfo, OnboardingLinkInfo, TransferInstrumentInfo} from "../typings/legalEntityManagement/models";
import {DocumentUpdate} from "../services/legalEntityManagement/documents";
import {businessLine, businessLines, document, legalEntity, onboardingLink, onboardingTheme, onboardingThemes, transferInstrument} from "../__mocks__/legalEntityManagement/responses";
import TransferEnum = TransferInstrumentInfo.TypeEnum;
import TypeEnum = LegalEntityInfo.TypeEnum
import DocEnum = Document.TypeEnum
import {onboardingLinkInfo} from "../__mocks__/legalEntityManagement/requests";
import LegalEntityManagement from "../services/legalEntityManagement";
let client: Client;
let legalEntityManagement: LegalEntityManagement;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.legalEntityManagementEndpoint}/${Client.LEGAL_ENTITY_MANAGEMENT_API_VERSION}`);
legalEntityManagement = new LegalEntityManagement(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("Legal Entity Management", (): void => {
const id = "123456789"
describe("LegalEntities", (): void => {
it("should support POST /legalEntities", async (): Promise<void> => {
scope.post("/legalEntities")
.reply(200, legalEntity);
const request: models.LegalEntityInfo = {
type : TypeEnum.Individual,
individual : undefined
};
const response: models.LegalEntity = await legalEntityManagement.LegalEntities.create(request);
expect(response.id).toBe(id);
expect(response.type).toBe("individual");
});
it("should support GET /legalEntities/{id}", async (): Promise<void> => {
scope.get(`/legalEntities/${id}`)
.reply(200, legalEntity);
const response: models.LegalEntity = await legalEntityManagement.LegalEntities.retrieve("123456789");
expect(response.id).toBe(id);
expect(response.type).toBe("individual");
});
it("should support PATCH /legalEntities/{id}", async (): Promise<void> => {
scope.patch(`/legalEntities/${id}`)
.reply(200, legalEntity);
const request: models.LegalEntityInfo = {
type : TypeEnum.Individual,
individual : undefined
};
const response: models.LegalEntity = await legalEntityManagement.LegalEntities.update(id, request);
expect(response.id).toBe(id);
expect(response.type).toBe("individual");
});
it("should support GET /legalEntities/{id}/BusinessLines", async (): Promise<void> => {
scope.get(`/legalEntities/${id}/businessLines`)
.reply(200, businessLines);
const response: models.BusinessLines = await legalEntityManagement.LegalEntities.listBusinessLines(id);
expect(response.businessLines).toEqual( [{
"capability": "receivePayments",
"id": "123456789",
"industryCode": "123456789",
"legalEntityId": "123456789",
"salesChannels": ["string"],
"sourceOfFunds": {
"acquiringBusinessLineId": "string",
"adyenProcessedFunds": false,
"description": "string",
"type": "business"
},
"webData": [{ "webAddress": "string" }],
"webDataExemption": { "reason": "noOnlinePresence" }
}]);
});
});
describe("Transfer Instruments", (): void => {
it("should support POST /transferInstruments", async (): Promise<void> => {
scope.post("/transferInstruments")
.reply(200, transferInstrument);
const request: models.TransferInstrumentInfo = {
type : TransferEnum.BankAccount,
legalEntityId : id,
bankAccount : {accountNumber: "string",
accountType: "string",
bankBicSwift: "string",
bankCity: "string",
bankCode: "string",
bankName: "string",
branchCode: "string",
checkCode: "string",
countryCode: "string",
currencyCode: "string",
iban: "string"
}
};
const response: models.TransferInstrument = await legalEntityManagement.TransferInstruments.create(request);
expect(response.id).toBe(id);
expect(response.type).toBe(TransferEnum.BankAccount);
});
it("should support GET /transferInstruments/{id}", async (): Promise<void> => {
scope.get(`/transferInstruments/${id}`)
.reply(200, transferInstrument);
const response: models.TransferInstrument = await legalEntityManagement.TransferInstruments.retrieve(id);
expect(response.id).toBe(id);
expect(response.type).toBe(TransferEnum.BankAccount);
});
it("should support PATCH /transferInstruments/{id}", async (): Promise<void> => {
scope.patch(`/transferInstruments/${id}`)
.reply(200, transferInstrument);
const request: models.TransferInstrumentInfo = {
type : TransferEnum.BankAccount,
legalEntityId : id,
bankAccount : {accountNumber: "string",
accountType: "string",
bankBicSwift: "string",
bankCity: "string",
bankCode: "string",
bankName: "string",
branchCode: "string",
checkCode: "string",
countryCode: "string",
currencyCode: "string",
iban: "string"
}
};
const response: models.TransferInstrument = await legalEntityManagement.TransferInstruments.update(id, request);
expect(response.id).toBe(id);
expect(response.type).toBe(TransferEnum.BankAccount);
});
it("should support DELETE /transferInstruments/{id}", async (): Promise<void> => {
scope.delete(`/transferInstruments/${id}`)
.reply(200);
await legalEntityManagement.TransferInstruments.delete(id);
expect(200);
});
});
describe("Business Lines", (): void => {
it("should support POST /businessLines", async (): Promise<void> => {
scope.post("/businessLines")
.reply(200, businessLine);
const request: models.BusinessLineInfo = {
capability: "receivePayments",
industryCode: id,
legalEntityId: id };
const response: models.BusinessLine = await legalEntityManagement.BusinessLineService.create(request);
expect(response.id).toBe(id);
expect(response.capability).toBe("receivePayments");
expect(response.industryCode).toBe(id);
expect(response.legalEntityId).toBe(id);
});
it("should support GET /businessLines/{id}", async (): Promise<void> => {
scope.get(`/businessLines/${id}`)
.reply(200, businessLine);
const response: models.BusinessLine = await legalEntityManagement.BusinessLineService.retrieve(id);
expect(response.id).toBe(id);
expect(response.capability).toBe("receivePayments");
});
it("should support PATCH /businessLines/{id}", async (): Promise<void> => {
scope.patch(`/businessLines/${id}`)
.reply(200, businessLine);
const request: models.BusinessLineInfo = {
capability: "receivePayments",
industryCode: id,
legalEntityId: id };
const response: models.BusinessLine = await legalEntityManagement.BusinessLineService.update(id, request);
expect(response.id).toBe(id);
expect(response.capability).toBe("receivePayments");
expect(response.industryCode).toBe(id);
expect(response.legalEntityId).toBe(id);
});
});
describe("Documents", (): void => {
it("should support POST /documents", async (): Promise<void> => {
scope.post("/documents")
.reply(200, document);
const request: DocumentUpdate = {
attachments: [{
content: "string",
contentType: "string",
filename: "string",
pageName: "string",
pageType: "string"
}],
description: "document",
owner: {
"id": "123456789",
"type": "passport"
},
type : DocEnum.DriversLicense
};
const response: models.Document = await legalEntityManagement.Documents.create(request);
expect(response.id).toBe(id);
expect(response.type).toBe(DocEnum.DriversLicense);
expect(response.owner).toEqual({id : "123456789", type : "passport" })
});
it("should support GET /documents/{id}", async (): Promise<void> => {
scope.get(`/documents/${id}`)
.reply(200, document);
const response: models.Document = await legalEntityManagement.Documents.retrieve(id);
expect(response.id).toBe(id);
expect(response.type).toBe(DocEnum.DriversLicense);
expect(response.owner).toEqual({id : "123456789", type : "passport" })
});
it("should support PATCH /documents/{id}", async (): Promise<void> => {
scope.patch(`/documents/${id}`)
.reply(200, document);
const request: DocumentUpdate = {
attachments: [{
content: "string",
contentType: "string",
filename: "string",
pageName: "string",
pageType: "string"
}],
description: "document",
owner: {
"id": "123456789",
"type": "passport"
},
type : DocEnum.DriversLicense
};
const response: models.Document = await legalEntityManagement.Documents.update(id, request);
expect(response.id).toBe(id);
expect(response.type).toBe(DocEnum.DriversLicense);
expect(response.owner).toEqual({id : "123456789", type : "passport" })
});
it("should support DELETE /documents/{id}", async (): Promise<void> => {
scope.delete(`/documents/${id}`)
.reply(200);
await legalEntityManagement.Documents.delete(id);
});
});
describe("OnboardingLinks and Themes", (): void => {
it("should support POST /onboardingLinks", async (): Promise<void> => {
scope.post(`/legalEntities/${id}/onboardingLinks`)
.reply(200, onboardingLink);
const request: OnboardingLinkInfo = onboardingLinkInfo;
const response: models.OnboardingLink = await legalEntityManagement.HostedOnboardingPage.create(id, request);
expect(response.url).toBe("https://your.redirect-url.com");
});
it("should support GET /themes", async (): Promise<void> => {
scope.get(`/themes`)
.reply(200, onboardingThemes);
const response: models.OnboardingThemes = await legalEntityManagement.HostedOnboardingPage.listThemes();
expect(response.themes[0].id).toEqual(id);
});
it("should support GET /themes/{id}", async (): Promise<void> => {
scope.get(`/themes/${id}`)
.reply(200, onboardingTheme);
const response: models.OnboardingTheme = await legalEntityManagement.HostedOnboardingPage.retrieveTheme(id);
expect(response.id).toBe(id);
});
});
});

View File

@@ -1,729 +0,0 @@
import nock from "nock";
import Client from "../client";
import { createClient } from "../__mocks__/base";
import { Management } from "../services";
import { management } from "../typings";
import * as requests from "../__mocks__/management/requests";
import * as responses from "../__mocks__/management/responses";
import HttpClientException from "../httpClient/httpClientException";
let client: Client;
let managementService: Management;
let scope: nock.Scope;
const merchantId = "merchantId";
const apiCredentialId = "apiCredentialId";
const originId = "originId";
const paymentMethodId = "paymentMethodId";
const payoutSettingsId = "payoutSettingsId";
const orderId = "orderId";
const userId = "userId";
const webhookId = "webhookId";
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.managementEndpoint}/${Client.MANAGEMENT_API_VERSION}`);
managementService = new Management(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("Management", (): void => {
describe("Me", (): void => {
test("Should properly handle error responses from API", async (): Promise<void> => {
scope.post("/me/allowedOrigins")
.reply(422, {
"type": "https://docs.adyen.com/errors/not-found",
"title": "Entity was not found",
"status": 422,
"detail": "The origin id is invalid or does not exist.",
"requestId": "KQZ5LXK2VMPRMC82",
"errorCode": "30_112",
});
try {
const createAllowedOriginRequest : management.CreateAllowedOriginRequest = {
domain: "test.com",
};
await managementService.Me.createAllowedOrigin(createAllowedOriginRequest);
fail("No exception was thrown");
} catch (error) {
expect(error instanceof HttpClientException).toBeTruthy();
if(error instanceof HttpClientException && error.responseBody) {
expect(JSON.parse(error.responseBody).requestId).toBe("KQZ5LXK2VMPRMC82");
} else {
fail("Error did not contain the expected data");
}
}
});
test("Should get API credential details based on the API Key used in the request", async (): Promise<void> => {
scope.get("/me")
.reply(200, {
"id": "S2-6262224667",
"username": "ws_123456@Company.Test",
"clientKey": "test_UCP6BO23234FFEFE33E4GWX63",
"allowedIpAddresses": [],
"roles": [
"Management API - Users read and write",
"Management API - Accounts read",
"Trigger webhook notifications",
"Management API - Payout Account Settings Read And Write",
"Manage LegalEntities via API",
"Manage associated partner accounts via API",
"PSP Pos initial configuration",
],
"_links": {
"self": {
"href": "https://management-test.adyen.com/v1/me"
},
"allowedOrigins": {
"href": "https://management-test.adyen.com/v1/me/allowedOrigins"
}
},
"companyName": "Test",
"active": true,
});
const meResponse: management.MeApiCredential = await managementService.Me.retrieve();
expect(meResponse.id).toEqual("S2-6262224667");
});
test("Should add an allowed origin to the list of allowed origins", async (): Promise<void> => {
scope.post("/me/allowedOrigins")
.reply(200, {
"id": "S2-45597C41735B6D75433E2B396553453ertcdt347675B4E3B413B4C4571522A6B2921",
"domain": "https://www.us.mystore.com",
"_links": {
"self": {
"href": "https://management-test.adyen.com/v1/me/allowedOrigins/S2-45597C41735B6D75433E2B396553453ertcdt347675B4E3B413B4C4571522A6B2921"
}
}
});
const allowedOriginRequest: management.AllowedOrigin = {
"domain": "https://www.us.mystore.com"
};
const allowedOriginsResponse: management.AllowedOrigin = await managementService.Me.createAllowedOrigin(allowedOriginRequest);
expect(allowedOriginsResponse.domain).toEqual("https://www.us.mystore.com");
});
test("Should get the list of allowed origins of a API credential based on the API key used in the request", async (): Promise<void> => {
scope.get("/me/allowedOrigins")
.reply(200, {
"data": [
{
"id": "S2-45597C41735B6D75433E2B396553453ertcdt347675B4E3B413B4C4571522A6B2921",
"domain": "https://www.us.mystore.com",
"_links": {
"self": {
"href": "https://management-test.adyen.com/v1/me/allowedOrigins/S2-45597C41735B6D75433E2B396553453ertcdt347675B4E3B413B4C4571522A6B2921"
}
}
}
]
});
const allowedOriginsResponse: management.AllowedOriginsResponse = await managementService.Me.retrieveAllowedOrigins();
expect(allowedOriginsResponse.data?.length).toEqual(1);
});
});
test("Should retrieve the details of the allowed origin specified in the path", async () => {
scope.get("/me/allowedOrigins/S2-123123123123123")
.reply(200, {
"id": "S2-123123123123123",
"domain": "https://www.us.mystore.com",
"_links": {
"self": {
"href": "https://management-test.adyen.com/v1/me/allowedOrigins/S2-123123123123123"
}
}
});
const allowedOriginResponse: management.AllowedOrigin = await managementService.Me.retrieveAllowedOrigin("S2-123123123123123");
expect(allowedOriginResponse.id).toEqual("S2-123123123123123");
});
test("Should remove the allowed origin specified in the path", async () => {
scope.delete("/me/allowedOrigins/S2-123123123123123").reply(204, {});
const allowedOriginResponse: Record<string, unknown> = await managementService.Me.deleteAllowerdOrigin("S2-123123123123123");
expect(scope.isDone()).toBe(true);
expect(Object.entries(allowedOriginResponse).length).toBe(0);
});
describe("MerchantAccount", (): void => {
it("should support GET /merchants", async (): Promise<void> => {
scope.get("/merchants?pageNumber=1&pageSize=1")
.reply(200, responses.listMerchantResponse);
const response: management.ListMerchantResponse = await managementService.MerchantAccount.list({
params: {
"pageNumber": "1",
"pageSize": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants", async (): Promise<void> => {
scope.post("/merchants")
.reply(200, responses.createMerchantResponse);
const response: management.CreateMerchantResponse = await managementService.MerchantAccount.create(requests.createMerchantRequest);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}`)
.reply(200, responses.merchant);
const response: management.Merchant = await managementService.MerchantAccount.retrieve(merchantId);
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/activate", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/activate`)
.reply(200, responses.requestActivationResponse);
const response: management.RequestActivationResponse = await managementService.MerchantAccount.activate(merchantId);
expect(response).toBeTruthy();
});
});
describe("MerchantAllowedOrigins", (): void => {
it("should support GET /merchants/{merchantId}/apiCredentials/{apiCredentialId}/allowedOrigins", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/allowedOrigins`)
.reply(200, responses.allowedOriginsResponse);
const response: management.AllowedOriginsResponse = await managementService.MerchantAllowedOrigins.list(merchantId, apiCredentialId);
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/apiCredentials/{apiCredentialId}/allowedOrigins", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/allowedOrigins`)
.reply(200, responses.allowedOriginsResponse);
const response: management.AllowedOriginsResponse = await managementService.MerchantAllowedOrigins.create(merchantId, apiCredentialId, requests.allowedOrigin);
expect(response).toBeTruthy();
});
it("should support DELETE /merchants/{merchantId}/apiCredentials/{apiCredentialId}/allowedOrigins/{originId}", async (): Promise<void> => {
scope.delete(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/allowedOrigins/${originId}`)
.reply(204);
await managementService.MerchantAllowedOrigins.delete(merchantId, apiCredentialId, originId);
});
it("should support GET /merchants/{merchantId}/apiCredentials/{apiCredentialId}/allowedOrigins/{originId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/allowedOrigins/${originId}`)
.reply(200, responses.allowedOrigin);
const response: management.AllowedOrigin = await managementService.MerchantAllowedOrigins.retrieve(merchantId, apiCredentialId, originId);
expect(response).toBeTruthy();
});
});
describe("MerchantApiCredentials", (): void => {
it("should support GET /merchants/{merchantId}/apiCredentials", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/apiCredentials?pageNumber=1&pageSize=1`)
.reply(200, responses.listMerchantApiCredentialsResponse);
const response: management.ListMerchantApiCredentialsResponse = await managementService.MerchantApiCredentials.list(merchantId, {
params: {
"pageNumber": "1",
"pageSize": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/apiCredentials", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/apiCredentials`)
.reply(200, responses.createApiCredentialResponse);
const response: management.CreateApiCredentialResponse = await managementService.MerchantApiCredentials.create(merchantId, requests.createMerchantApiCredentialRequest);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/apiCredentials/{apiCredentialId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}`)
.reply(200, responses.apiCredential);
const response: management.ApiCredential = await managementService.MerchantApiCredentials.retrieve(merchantId, apiCredentialId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/apiCredentials/{apiCredentialId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}`)
.reply(200, responses.apiCredential);
const response: management.ApiCredential = await managementService.MerchantApiCredentials.update(merchantId, apiCredentialId, requests.updateMerchantApiCredentialRequest);
expect(response).toBeTruthy();
});
});
describe("MerchantApiKey", (): void => {
it("should support POST /merchants/{merchantId}/apiCredentials/{apiCredentialId}/generateApiKey", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/generateApiKey`)
.reply(200, responses.generateApiKeyResponse);
const response: management.GenerateApiKeyResponse = await managementService.MerchantApiKey.create(merchantId, apiCredentialId);
expect(response).toBeTruthy();
});
});
describe("MerchantClientKey", (): void => {
it("should support POST /merchants/{merchantId}/apiCredentials/{apiCredentialId}/generateClientKey", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/apiCredentials/${apiCredentialId}/generateClientKey`)
.reply(200, responses.generateClientKeyResponse);
const response: management.GenerateClientKeyResponse = await managementService.MerchantClientKey.create(merchantId, apiCredentialId);
expect(response).toBeTruthy();
});
});
describe("MerchantPaymentMethods", (): void => {
it("should support GET /merchants/{merchantId}/paymentMethodSettings", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/paymentMethodSettings?storeId=1&businessLineId=1&pageNumber=1&pageSize=1`)
.reply(200, responses.paymentMethodResponse);
const response: management.PaymentMethodResponse = await managementService.MerchantPaymentMethods.listPaymentMethodSettings(merchantId, {
params: {
"storeId": "1",
"businessLineId": "1",
"pageSize": "1",
"pageNumber": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/paymentMethodSettings", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/paymentMethodSettings`)
.reply(200, responses.paymentMethod);
const response: management.PaymentMethod = await managementService.MerchantPaymentMethods.create(merchantId, {
...requests.paymentMethodSetupInfo,
type: management.PaymentMethodSetupInfo.TypeEnum.Ideal
});
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/paymentMethodSettings/{paymentMethodId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/paymentMethodSettings/${paymentMethodId}`)
.reply(200, responses.paymentMethod);
const response: management.PaymentMethod = await managementService.MerchantPaymentMethods.retrieve(merchantId, paymentMethodId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/paymentMethodSettings/{paymentMethodId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/paymentMethodSettings/${paymentMethodId}`)
.reply(200, responses.paymentMethod);
const response: management.PaymentMethod = await managementService.MerchantPaymentMethods.update(merchantId, paymentMethodId, requests.updatePaymentMethodInfo);
expect(response).toBeTruthy();
});
});
describe("MerchantPayoutSettings", (): void => {
it("should support GET /merchants/{merchantId}/payoutSettings", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/payoutSettings`)
.reply(200, responses.payoutSettingsResponse);
const response: management.PayoutSettingsResponse = await managementService.MerchantPayoutSettings.listPayoutSettings(merchantId);
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/payoutSettings", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/payoutSettings`)
.reply(200, responses.payoutSettings);
const response: management.PayoutSettings = await managementService.MerchantPayoutSettings.create(merchantId, requests.payoutSettingsRequest);
expect(response).toBeTruthy();
});
it("should support DELETE /merchants/{merchantId}/payoutSettings/{payoutSettingsId}", async (): Promise<void> => {
scope.delete(`/merchants/${merchantId}/payoutSettings/${payoutSettingsId}`)
.reply(200);
await managementService.MerchantPayoutSettings.delete(merchantId, payoutSettingsId);
});
it("should support GET /merchants/{merchantId}/payoutSettings/{payoutSettingsId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/payoutSettings/${payoutSettingsId}`)
.reply(200, responses.payoutSettings);
const response: management.PayoutSettings = await managementService.MerchantPayoutSettings.retrieve(merchantId, payoutSettingsId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/payoutSettings/{payoutSettingsId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/payoutSettings/${payoutSettingsId}`)
.reply(200, responses.payoutSettings);
const response: management.PayoutSettings = await managementService.MerchantPayoutSettings.update(merchantId, payoutSettingsId, requests.updatePayoutSettingsRequest);
expect(response).toBeTruthy();
});
});
describe("MerchantTerminalOrders", (): void => {
it("should support GET /merchants/{merchantId}/billingEntities", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/billingEntities?name=bill`)
.reply(200, responses.billingEntitiesResponse);
const response: management.BillingEntitiesResponse = await managementService.MerchantTerminalOrders.listBillingEntities(merchantId, {
params: {
"name": "bill"
}
});
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/shippingLocations", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/shippingLocations?name=1&offset=1&limit=1`)
.reply(200, responses.shippingLocationsResponse);
const response: management.ShippingLocationsResponse = await managementService.MerchantTerminalOrders.listShippingLocations(merchantId, {
params: {
"name": "1",
"offset": "1",
"limit": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/shippingLocations", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/shippingLocations`)
.reply(200, responses.shippingLocation);
const response: management.ShippingLocation = await managementService.MerchantTerminalOrders.createShippingLocation(merchantId, requests.shippingLocation);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/terminalModels", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalModels`)
.reply(200, responses.terminalModelsResponse);
const response: management.TerminalModelsResponse = await managementService.MerchantTerminalOrders.listTerminalModels(merchantId);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/terminalOrders", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalOrders?customerOrderReference=1&status=1&offset=1&limit=1`)
.reply(200, responses.terminalOrdersResponse);
const response: management.TerminalOrdersResponse = await managementService.MerchantTerminalOrders.listTerminalOrders(merchantId, {
params: {
"customerOrderReference": "1",
"status": "1",
"offset": "1",
"limit": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/terminalOrders", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/terminalOrders`)
.reply(200, responses.terminalOrder);
const response: management.TerminalOrder = await managementService.MerchantTerminalOrders.create(merchantId, requests.terminalOrderRequest);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/terminalOrders/{orderId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalOrders/${orderId}`)
.reply(200, responses.terminalOrder);
const response: management.TerminalOrder = await managementService.MerchantTerminalOrders.retrieve(merchantId, orderId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/terminalOrders/{orderId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/terminalOrders/${orderId}`)
.reply(200, responses.terminalOrder);
const response: management.TerminalOrder = await managementService.MerchantTerminalOrders.update(merchantId, orderId, requests.terminalOrderRequest);
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/terminalOrders/{orderId}/cancel", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/terminalOrders/${orderId}/cancel`)
.reply(200, responses.terminalOrder);
const response: management.TerminalOrder = await managementService.MerchantTerminalOrders.cancel(merchantId, orderId);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/terminalProducts", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalProducts?country=1&terminalModelId=1&offset=1&limit=1`)
.reply(200, responses.terminalProductsResponse);
const response: management.TerminalProductsResponse = await managementService.MerchantTerminalOrders.listTerminalProducts(merchantId, {
params: {
"country": "1",
"terminalModelId": "1",
"offset": "1",
"limit": "1"
}
});
expect(response).toBeTruthy();
});
});
describe("MerchantTerminalSettings", (): void => {
it("should support GET /merchants/{merchantId}/terminalLogos", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalLogos?model=1`)
.reply(200, responses.logo);
const response: management.Logo = await managementService.MerchantTerminalSettings.retrieveLogo(merchantId, {
params: {
"model": "1"
}
});
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/terminalLogos", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/terminalLogos?model=1`)
.reply(200, responses.logo);
const response: management.Logo = await managementService.MerchantTerminalSettings.updateLogo(merchantId, requests.logo, {
params: {
"model": "1"
}
});
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/terminalSettings", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/terminalSettings`)
.reply(200, responses.terminalSettings);
const response: management.TerminalSettings = await managementService.MerchantTerminalSettings.retrieve(merchantId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/terminalSettings", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/terminalSettings`)
.reply(200, responses.terminalSettings);
const response: management.TerminalSettings = await managementService.MerchantTerminalSettings.update(merchantId, requests.terminalSettings);
expect(response).toBeTruthy();
});
});
describe("MerchantUsers", (): void => {
it("should support GET /merchants/{merchantId}/users", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/users?pageNumber=1&pageSize=1`)
.reply(200, responses.listMerchantUsersResponse);
const response: management.ListMerchantUsersResponse = await managementService.MerchantUsers.list(merchantId, {
params: {
"pageNumber": "1",
"pageSize": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/users", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/users`)
.reply(200, responses.createUserResponse);
const response: management.CreateUserResponse = await managementService.MerchantUsers.create(merchantId, requests.createMerchantUserRequest);
expect(response).toBeTruthy();
});
it("should support GET /merchants/{merchantId}/users/{userId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/users/${userId}`)
.reply(200, responses.user);
const response: management.User = await managementService.MerchantUsers.retrieve(merchantId, userId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/users/{userId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/users/${userId}`)
.reply(200, responses.user);
const response: management.User = await managementService.MerchantUsers.update(merchantId, userId, requests.updateMerchantUserRequest);
expect(response).toBeTruthy();
});
});
describe("MerchantWebhooks", (): void => {
it("should support GET /merchants/{merchantId}/webhooks", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/webhooks?pageNumber=1&pageSize=1`)
.reply(200, responses.listWebhooksResponse);
const response: management.ListWebhooksResponse = await managementService.MerchantWebhooks.list(merchantId, {
params: {
"pageNumber": "1",
"pageSize": "1"
}
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/webhooks", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/webhooks`)
.reply(200, responses.webhook);
const response: management.Webhook = await managementService.MerchantWebhooks.create(merchantId, {
...requests.createMerchantWebhookRequest,
communicationFormat: management.CreateMerchantWebhookRequest.CommunicationFormatEnum.Json,
networkType: management.CreateMerchantWebhookRequest.NetworkTypeEnum.Public,
sslVersion: management.CreateMerchantWebhookRequest.SslVersionEnum.Tls
});
expect(response).toBeTruthy();
});
it("should support DELETE /merchants/{merchantId}/webhooks/{webhookId}", async (): Promise<void> => {
scope.delete(`/merchants/${merchantId}/webhooks/${webhookId}`)
.reply(204);
await managementService.MerchantWebhooks.delete(merchantId, webhookId);
});
it("should support GET /merchants/{merchantId}/webhooks/{webhookId}", async (): Promise<void> => {
scope.get(`/merchants/${merchantId}/webhooks/${webhookId}`)
.reply(200, responses.webhook);
const response: management.Webhook = await managementService.MerchantWebhooks.retrieve(merchantId, webhookId);
expect(response).toBeTruthy();
});
it("should support PATCH /merchants/{merchantId}/webhooks/{webhookId}", async (): Promise<void> => {
scope.patch(`/merchants/${merchantId}/webhooks/${webhookId}`)
.reply(200, responses.webhook);
const response: management.Webhook = await managementService.MerchantWebhooks.update(merchantId, webhookId, {
...requests.updateMerchantWebhookRequest,
communicationFormat: management.CreateMerchantWebhookRequest.CommunicationFormatEnum.Soap,
networkType: management.CreateMerchantWebhookRequest.NetworkTypeEnum.Local,
sslVersion: management.CreateMerchantWebhookRequest.SslVersionEnum.Sslv3
});
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/webhooks/{webhookId}/generateHmac", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/webhooks/${webhookId}/generateHmac`)
.reply(200, responses.generateHmacKeyResponse);
const response: management.GenerateHmacKeyResponse = await managementService.MerchantWebhooks.generateHmac(merchantId, webhookId);
expect(response).toBeTruthy();
});
it("should support POST /merchants/{merchantId}/webhooks/{webhookId}/test", async (): Promise<void> => {
scope.post(`/merchants/${merchantId}/webhooks/${webhookId}/test`)
.reply(200, responses.testWebhookResponse);
const testWebhookRequest: management.TestWebhookRequest = {
"notification": {
"amount": {
"currency": "string",
"value": 0
},
"eventCode": "string",
"eventDate": new Date(2022, 6, 15),
"merchantReference": "string",
"paymentMethod": "string",
"reason": "string",
"success": false
},
"types": ["string"]
};
const response: management.TestWebhookResponse = await managementService.MerchantWebhooks.test(merchantId, webhookId, testWebhookRequest);
expect(response).toBeTruthy();
});
});
describe("AllowedOriginsMerchantLevelApi", (): void => {
test("Delete an allowed origin", async () => {
scope.delete("/merchants/foo/apiCredentials/BAR123/allowedOrigins/fishy%20one").reply(204);
await managementService.AllowedOriginsMerchantLevelApi
.deleteAllowedOrigin("foo", "BAR123", "fishy one");
});
test("Create an allowed origin", async () => {
const requestBody = {
"domain": "https://www.eu.mystore.com"
};
scope.post("/merchants/YOUR_MERCHANT_ACCOUNT/apiCredentials/YOUR_API_CREDENTIAL/allowedOrigins", requestBody)
.reply(200, {
"id": "YOUR_ALLOWED_ORIGIN",
"data": [
{
"domain": "https://www.eu.mystore.com",
}
],
"_links": {
"self": {
"href": "https://management-test.adyen.com/v1/merchants/YOUR_MERCHANT_ACCOUNT/apiCredentials/YOUR_API_CREDENTIAL/allowedOrigins/YOUR_ALLOWED_ORIGIN"
}
}
});
const response: management.AllowedOriginsResponse = await managementService.AllowedOriginsMerchantLevelApi
.createAllowedOrigin("YOUR_MERCHANT_ACCOUNT", "YOUR_API_CREDENTIAL", {
domain: "https://www.eu.mystore.com",
});
expect(response.data![0].domain).toEqual("https://www.eu.mystore.com");
});
});
});

View File

@@ -1,353 +0,0 @@
import nock from "nock";
import {createClient} from "../__mocks__/base";
import Checkout from "../services/checkout";
import Client from "../client";
import {
CreatePaymentAmountUpdateRequest,
CreatePaymentCancelRequest,
CreatePaymentCaptureRequest,
CreatePaymentRefundRequest, CreatePaymentReversalRequest,
CreateStandalonePaymentCancelRequest,
PaymentAmountUpdateResource,
PaymentCancelResource,
PaymentCaptureResource, PaymentRefundResource, PaymentReversalResource,
StandalonePaymentCancelResource
} from "../typings/checkout/models";
import HttpClientException from "../httpClient/httpClientException";
const invalidModificationResult = {
"status": 422,
"errorCode": "167",
"message": "Original pspReference required for this operation",
"errorType": "validation"
};
const createAmountUpdateRequest = (): CreatePaymentAmountUpdateRequest => {
return {
reference: "863620292981235A",
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420
},
reason: CreatePaymentAmountUpdateRequest.ReasonEnum.DelayedCharge
};
};
const createAmountUpdateResponse = (): PaymentAmountUpdateResource => {
return {
paymentPspReference: "863620292981235A",
pspReference: "863620292981235B",
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420,
},
reason: CreatePaymentAmountUpdateRequest.ReasonEnum.DelayedCharge,
status: PaymentAmountUpdateResource.StatusEnum.Received,
};
};
const createCancelsRequest = (): CreatePaymentCancelRequest => {
return {
reference: "863620292981235B",
merchantAccount: process.env.ADYEN_MERCHANT!,
};
};
const createCancelsResponse = (): PaymentCancelResource => {
return {
merchantAccount: process.env.ADYEN_MERCHANT!,
pspReference: "863620292981235B",
paymentPspReference: "863620292981235A",
status: PaymentCancelResource.StatusEnum.Received,
};
};
const createStandaloneCancelsRequest = (): CreateStandalonePaymentCancelRequest => {
return {
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
paymentReference: "863620292981235B",
};
};
const createStandaloneCancelsResponse = (): StandalonePaymentCancelResource => {
return {
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
paymentReference: "863620292981235B",
pspReference: "863620292981235A",
status: StandalonePaymentCancelResource.StatusEnum.Received,
};
};
const createCapturesRequest = (): CreatePaymentCaptureRequest => {
return {
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420,
}
};
};
function createCapturesResponse(): PaymentCaptureResource {
return {
paymentPspReference: "863620292981235A",
pspReference: "863620292981235B",
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420,
},
status: PaymentCaptureResource.StatusEnum.Received,
};
}
const createRefundsRequest = (): CreatePaymentRefundRequest => {
return {
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420,
}
};
};
const createRefundsResponse = (): PaymentRefundResource => {
return {
paymentPspReference: "863620292981235A",
pspReference: "863620292981235B",
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
amount: {
currency: "EUR",
value: 420,
},
status: PaymentRefundResource.StatusEnum.Received,
};
};
const createReversalsRequest = (): CreatePaymentReversalRequest => {
return {
merchantAccount: process.env.ADYEN_MERCHANT!
};
};
const createReversalsResponse = (): PaymentReversalResource => {
return {
paymentPspReference: "863620292981235A",
pspReference: "863620292981235B",
reference: "reference",
merchantAccount: process.env.ADYEN_MERCHANT!,
status: PaymentRefundResource.StatusEnum.Received,
};
};
let client: Client;
let checkout: Checkout;
let scope: nock.Scope;
const paymentPspReference = "863620292981235A";
const invalidPaymentPspReference = "invalid_psp_reference";
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
checkout = new Checkout(client);
scope = nock(`${client.config.checkoutEndpoint}/${Client.CHECKOUT_API_VERSION}`);
});
afterEach(() => {
nock.cleanAll();
});
describe("Modification", (): void => {
test("should perform an amount update request", async (): Promise<void> => {
const request = createAmountUpdateRequest();
scope.post(`/payments/${paymentPspReference}/amountUpdates`)
.reply(200, createAmountUpdateResponse());
try {
const result = await checkout.amountUpdates(paymentPspReference, request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should fail to perform an amount update request", async (): Promise<void> => {
expect.assertions(2);
const request = createAmountUpdateRequest();
scope.post(`/payments/${invalidPaymentPspReference}/amountUpdates`)
.reply(422, invalidModificationResult);
try {
await checkout.amountUpdates(invalidPaymentPspReference, request);
} catch (e) {
if(e instanceof HttpClientException) {
if(e.statusCode) expect(e.statusCode).toBe(422);
expect(e.message).toContain("Original pspReference required for this operation");
} else {
fail();
}
}
});
test("should perform a cancels request", async (): Promise<void> => {
const request = createCancelsRequest();
scope.post(`/payments/${paymentPspReference}/cancels`)
.reply(200, createCancelsResponse());
try {
const result = await checkout.cancels(paymentPspReference, request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should fail to perform a cancels request", async (): Promise<void> => {
expect.assertions(2);
const request = createCancelsRequest();
scope.post(`/payments/${invalidPaymentPspReference}/cancels`)
.reply(422, invalidModificationResult);
try {
await checkout.cancels(invalidPaymentPspReference, request);
} catch (e) {
if(e instanceof HttpClientException) {
if(e.statusCode) expect(e.statusCode).toBe(422);
expect(e.message).toContain("Original pspReference required for this operation");
} else {
fail();
}
}
});
test("should perform a standalone cancels request", async (): Promise<void> => {
const request = createStandaloneCancelsRequest();
scope.post("/cancels")
.reply(200, createStandaloneCancelsResponse());
try {
const result = await checkout.cancelsStandalone(request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should perform a captures request", async (): Promise<void> => {
const request = createCapturesRequest();
scope.post(`/payments/${paymentPspReference}/captures`)
.reply(200, createCapturesResponse());
try {
const result = await checkout.captures(paymentPspReference, request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should fail to perform a captures request", async (): Promise<void> => {
expect.assertions(2);
const request = createCapturesRequest();
scope.post(`/payments/${invalidPaymentPspReference}/captures`)
.reply(422, invalidModificationResult);
try {
await checkout.captures(invalidPaymentPspReference, request);
} catch (e) {
if(e instanceof HttpClientException) {
if(e.statusCode) expect(e.statusCode).toBe(422);
expect(e.message).toContain("Original pspReference required for this operation");
} else {
fail();
}
}
});
test("should perform a refunds request", async (): Promise<void> => {
const request = createRefundsRequest();
scope.post(`/payments/${paymentPspReference}/refunds`)
.reply(200, createRefundsResponse());
try {
const result = await checkout.refunds(paymentPspReference, request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should fail to perform a refunds request", async (): Promise<void> => {
expect.assertions(2);
const request = createRefundsRequest();
scope.post(`/payments/${invalidPaymentPspReference}/refunds`)
.reply(422, invalidModificationResult);
try {
await checkout.refunds(invalidPaymentPspReference, request);
} catch (e) {
if(e instanceof HttpClientException) {
if(e.statusCode) expect(e.statusCode).toBe(422);
expect(e.message).toContain("Original pspReference required for this operation");
} else {
fail();
}
}
});
test("should perform a reversals request", async (): Promise<void> => {
const request = createReversalsRequest();
scope.post(`/payments/${paymentPspReference}/reversals`)
.reply(200, createReversalsResponse());
try {
const result = await checkout.reversals(paymentPspReference, request);
expect(result).toBeTruthy();
} catch (e) {
if(e instanceof Error) {
if(e.message) fail(e.message);
} else {
fail();
}
}
});
test("should fail to perform a reversals request", async (): Promise<void> => {
expect.assertions(2);
const request = createReversalsRequest();
scope.post(`/payments/${invalidPaymentPspReference}/reversals`)
.reply(422, invalidModificationResult);
try {
await checkout.reversals(invalidPaymentPspReference, request);
} catch (e) {
if(e instanceof HttpClientException) {
if(e.statusCode) expect(e.statusCode).toBe(422);
expect(e.message).toContain("Original pspReference required for this operation");
} else {
fail();
}
}
});
});

View File

@@ -4,9 +4,7 @@ import captureFalse from "../__mocks__/notification/captureFalse.json";
import refundTrue from "../__mocks__/notification/refundTrue.json";
import refundFalse from "../__mocks__/notification/refundFalse.json";
import NotificationRequest from "../notification/notificationRequest";
import { Notification, NotificationRequestItem } from "../typings/notification/models";
import NotificationEnum = NotificationRequestItem.EventCodeEnum;
import SuccessEnum = NotificationRequestItem.SuccessEnum;
import {Notification, NotificationEnum, NotificationRequestItem} from "../typings/notification";
describe("Notification Test", function (): void {
it("should return authorisation success", function (): void {
@@ -15,10 +13,9 @@ describe("Notification Test", function (): void {
if (notificationRequest.notificationItems) {
const notificationRequestItem: NotificationRequestItem = notificationRequest.notificationItems[0];
expect(NotificationEnum.Authorisation).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === SuccessEnum.True).toBeTruthy();
expect(NotificationEnum.EVENT_CODE_AUTHORISATION).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === "true").toBeTruthy();
expect(notificationRequestItem.pspReference).toEqual("123456789");
expect(notificationRequestItem.additionalData!.paymentLinkId).toEqual("ABCDEFG");
} else {
fail();
}
@@ -30,8 +27,8 @@ describe("Notification Test", function (): void {
if (notificationRequest.notificationItems) {
const notificationRequestItem = notificationRequest.notificationItems[0];
expect(NotificationEnum.Capture).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === SuccessEnum.True).toBeTruthy();
expect(NotificationEnum.EVENT_CODE_CAPTURE).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === "true").toBeTruthy();
expect(notificationRequestItem.pspReference).toEqual("PSP_REFERENCE");
expect(notificationRequestItem.originalReference).toEqual("ORIGINAL_PSP");
} else {
@@ -45,8 +42,8 @@ describe("Notification Test", function (): void {
if (notificationRequest.notificationItems) {
const notificationRequestItem = notificationRequest.notificationItems[0];
expect(NotificationEnum.Capture).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === SuccessEnum.True).toBeFalsy();
expect(NotificationEnum.EVENT_CODE_CAPTURE).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === "true").toBeFalsy();
expect(notificationRequestItem.pspReference).toEqual("PSP_REFERENCE");
expect(notificationRequestItem.originalReference).toEqual("ORIGINAL_PSP");
} else {
@@ -60,8 +57,8 @@ describe("Notification Test", function (): void {
if (notificationRequest.notificationItems) {
const notificationRequestItem = notificationRequest.notificationItems[0];
expect(NotificationEnum.Refund).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === SuccessEnum.True).toBeTruthy();
expect(NotificationEnum.EVENT_CODE_REFUND).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === "true").toBeTruthy();
expect(notificationRequestItem.pspReference).toEqual("PSP_REFERENCE");
expect(notificationRequestItem.originalReference).toEqual("ORIGINAL_PSP");
expect(notificationRequestItem.eventDate).toBeDefined();
@@ -76,8 +73,8 @@ describe("Notification Test", function (): void {
if (notificationRequest.notificationItems) {
const notificationRequestItem = notificationRequest.notificationItems[0];
expect(NotificationEnum.Refund).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === SuccessEnum.True).toBeFalsy();
expect(NotificationEnum.EVENT_CODE_REFUND).toEqual(notificationRequestItem.eventCode);
expect(notificationRequestItem.success === "true").toBeFalsy();
expect(notificationRequestItem.pspReference).toEqual("PSP_REFERENCE");
expect(notificationRequestItem.originalReference).toEqual("ORIGINAL_PSP");
expect(notificationRequestItem.eventDate).toBeDefined();

View File

@@ -1,14 +1,15 @@
import nock from "nock";
import { createClient } from "../__mocks__/base";
import {createMockClientFromResponse} from "../__mocks__/base";
import Payout from "../services/payout";
import Client from "../client";
import { payouts } from "../typings";
import { ApiConstants } from "../constants/apiConstants";
import StoreDetailRequest = IPayouts.StoreDetailRequest;
import {ApiConstants} from "../constants/apiConstants";
const storeDetailAndSubmitThirdParty = JSON.stringify({
additionalData: {
fraudResultType: "GREEN",
fraudManualReview: "false",
},
pspReference: "8515131751004933",
resultCode: "[payout-submit-received]"
@@ -23,56 +24,49 @@ const storeDetail = JSON.stringify({
const amountAndReference = {
amount: {
value: 100,
currency: "EUR"
value: 1000,
currency: "USD"
},
reference: "randomReference",
};
const defaultData = {
dateOfBirth: new Date(),
dateOfBirth: (new Date()).toISOString(),
nationality: "NL",
shopperEmail: "johndoe@email.com",
shopperReference: "shopperReference",
};
const mockStoreDetailRequest = (merchantAccount: string = process.env.ADYEN_MERCHANT!): payouts.StoreDetailRequest => ({
const mockStoreDetailRequest = (merchantAccount: string): IPayouts.StoreDetailRequest => ({
...defaultData,
card: {
cvc: "737",
expiryMonth: "03",
expiryYear: "2020",
number: "4111111111111111",
holderName: "John Smith"
},
entityType: payouts.StoreDetailRequest.EntityTypeEnum.Company,
entityType: "NaturalPerson",
recurring: {
contract: payouts.Recurring.ContractEnum.Payout,
contract: "ONECLICK"
},
merchantAccount,
});
const mockSubmitRequest = (merchantAccount: string = process.env.ADYEN_MERCHANT!): payouts.SubmitRequest => ({
const mockSubmitRequest = (merchantAccount: string): IPayouts.SubmitRequest => ({
selectedRecurringDetailReference: "LATEST",
recurring: {
contract: payouts.Recurring.ContractEnum.Payout
contract: "ONECLICK"
},
...defaultData,
...amountAndReference,
merchantAccount,
});
const mockStoreDetailAndSubmitRequest = (merchantAccount?: string): payouts.StoreDetailAndSubmitRequest => ({
const mockStoreDetailAndSubmitRequest = (merchantAccount: string): IPayouts.StoreDetailAndSubmitRequest => ({
...amountAndReference,
...(mockStoreDetailRequest(merchantAccount)),
});
});
const mockPayoutRequest = (merchantAccount: string = process.env.ADYEN_MERCHANT!): payouts.PayoutRequest => ({
const mockPayoutRequest = (merchantAccount: string): IPayouts.PayoutRequest => ({
...amountAndReference,
...defaultData,
card: {
expiryMonth: "03",
expiryYear: "2030",
expiryMonth: "10",
expiryYear: "2020",
holderName: "John Smith",
number: "4111111111111111",
},
@@ -80,80 +74,23 @@ const mockPayoutRequest = (merchantAccount: string = process.env.ADYEN_MERCHANT!
});
let client: Client;
let clientStore: Client;
let clientReview: Client;
let payoutService: Payout;
let payout: Payout;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
clientStore = createClient(process.env.ADYEN_STOREPAYOUT_APIKEY);
clientReview = createClient(process.env.ADYEN_REVIEWPAYOUT_APIKEY);
client = createMockClientFromResponse();
scope = nock(`${client.config.endpoint}/pal/servlet/Payout/${Client.API_VERSION}`);
payoutService = new Payout(client);
});
afterEach((): void => {
nock.cleanAll();
payout = new Payout(client);
});
describe("PayoutTest", function (): void {
test("should succeed on store detail and submit third party", async function (): Promise<void> {
payoutService = new Payout(clientStore);
const request: payouts.StoreDetailAndSubmitRequest = mockStoreDetailAndSubmitRequest();
scope.post("/storeDetailAndSubmitThirdParty").reply(200, storeDetailAndSubmitThirdParty);
it("should succeed on store detail and submit third party", async function (): Promise<void> {
const request: IPayouts.StoreDetailAndSubmitRequest = mockStoreDetailAndSubmitRequest(`${client.config.merchantAccount}`);
scope.post("/storeDetail").reply(200, storeDetailAndSubmitThirdParty);
const result = await payoutService.storeDetailAndSubmitThirdParty(request);
const result = await payout.storeDetail(request);
expect(result.resultCode).toEqual("[payout-submit-received]");
expect(result.pspReference).toBeTruthy();
});
test("should succeed on store detail", async function (): Promise<void> {
payoutService = new Payout(clientStore);
scope.post("/storeDetail").reply(200, storeDetail);
const request: payouts.StoreDetailRequest = mockStoreDetailRequest();
const result = await payoutService.storeDetail(request);
expect("Success").toEqual(result.resultCode);
expect(result.pspReference).toBeTruthy();
expect(result.recurringDetailReference).toBeTruthy();
});
test("should succeed on confirm third party", async function (): Promise<void> {
payoutService = new Payout(clientStore);
scope.post("/storeDetail").reply(200, storeDetail);
const storeRequest: payouts.StoreDetailRequest = mockStoreDetailRequest();
const storeResult = await payoutService.storeDetail(storeRequest);
payoutService = new Payout(clientReview);
scope.post("/confirmThirdParty")
.reply(200, {
pspReference: "8815131762537886",
response: "[payout-confirm-received]"
});
const request: payouts.ModifyRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
originalReference: storeResult.pspReference
};
const result = await payoutService.confirmThirdParty(request);
expect(result.response).toEqual("[payout-confirm-received]");
expect(result.pspReference).toBeTruthy();
});
test("should succeed on submit third party", async function (): Promise<void> {
payoutService = new Payout(clientStore);
scope.post("/submitThirdParty").reply(200, storeDetailAndSubmitThirdParty);
const request: payouts.SubmitRequest = mockSubmitRequest();
const result = await payoutService.submitThirdparty(request);
expect(result.resultCode).toEqual("[payout-submit-received]");
expect(result.pspReference).toBeTruthy();
expect(result.pspReference).toEqual("8515131751004933");
if (result.additionalData) {
expect(result.additionalData[ApiConstants.FRAUD_RESULT_TYPE]).toEqual("GREEN");
@@ -161,38 +98,74 @@ describe("PayoutTest", function (): void {
}
});
test("should succeed on decline third party", async function (): Promise<void> {
payoutService = new Payout(clientStore);
it("should succeed on store detail", async function (): Promise<void> {
scope.post("/storeDetail").reply(200, storeDetail);
const storeRequest: payouts.StoreDetailRequest = mockStoreDetailRequest();
const storeResult = await payoutService.storeDetail(storeRequest);
const request: StoreDetailRequest = mockStoreDetailRequest("MOCKED_MERCHANT_ACC");
const result = await payout.storeDetail(request);
payoutService = new Payout(clientReview);
const request: payouts.ModifyRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
originalReference: storeResult.pspReference
};
scope.post("/declineThirdParty")
.reply(200, {
pspReference: "8815131762537886",
response: "[payout-decline-received]"
});
const result = await payoutService.declineThirdParty(request);
expect(result.response).toEqual("[payout-decline-received]");
expect(result.pspReference).toBeTruthy();
expect("Success").toEqual(result.resultCode);
expect("8515136787207087").toEqual(result.pspReference);
expect("8415088571022720").toEqual(result.recurringDetailReference);
});
test("should succeed on payout", async function (): Promise<void> {
it("should succeed on confirm third party", async function (): Promise<void> {
scope.post("/confirmThirdParty")
.reply(200, {
pspReference: "8815131762537886",
response: "[payout-confirm-received]"
});
const request: IPayouts.ModifyRequest = {
merchantAccount: "MOCKED_MERCHANT_ACCOUNT",
originalReference: "reference"
};
const result = await payout.confirmThirdParty(request);
expect(result.response).toEqual("[payout-confirm-received]");
expect(result.pspReference).toEqual("8815131762537886");
});
it("should succeed on submit third party", async function (): Promise<void> {
scope.post("/submitThirdParty").reply(200, storeDetailAndSubmitThirdParty);
const request: IPayouts.SubmitRequest = mockSubmitRequest("MOCKED_MERCHANT_ACC");
const result = await payout.submitThirdparty(request);
expect(result.resultCode).toEqual("[payout-submit-received]");
expect(result.pspReference).toEqual("8515131751004933");
if (result.additionalData) {
expect(result.additionalData[ApiConstants.FRAUD_RESULT_TYPE]).toEqual("GREEN");
expect(result.additionalData[ApiConstants.FRAUD_MANUAL_REVIEW]).toEqual("false");
}
});
it("should succeed on decline third party", async function (): Promise<void> {
scope.post("/storeDetailAndSubmitThirdParty").reply(200, {
pspReference: "8815131762537886",
response: "[payout-confirm-received]"
});
const request: IPayouts.ModifyRequest = {
merchantAccount: "MOCKED_MERCHANT_ACC",
originalReference: "reference"
};
const result = await payout.declineThirdParty(request);
expect(result.response).toEqual("[payout-confirm-received]");
expect(result.pspReference).toEqual("8815131762537886");
});
it("should succeed on payout", async function (): Promise<void> {
scope.post("/payout").reply(200, {
pspReference: "8815131762537886",
resultCode: "Received",
});
const request = mockPayoutRequest();
const result = await payoutService.payout(request);
const request = mockPayoutRequest("MOCKED_MERCHANT_ACC");
const result = await payout.payout(request);
expect(result.resultCode).toEqual("Received");
expect(result.pspReference).toBeTruthy();
expect(result.pspReference).toEqual("8815131762537886");
});
});
});

View File

@@ -1,611 +0,0 @@
import nock from "nock";
import { createMock } from "ts-auto-mock";
import { createBasicAuthClient } from "../__mocks__/base";
import { documentContent } from "../__mocks__/platforms/documentContent";
import { Client, Platforms } from "../index";
import * as A from "../typings/platformsAccount/models";
import F = IPlatformsFund;
import N = IPlatformsNotificationConfiguration;
import AccountHolderDetails = A.AccountHolderDetails;
import NotificationConfigurationDetails = N.NotificationConfigurationDetails;
import HttpClientException from "../httpClient/httpClientException";
import { GetOnboardingUrlRequest, GetOnboardingUrlResponse, GetPciUrlRequest, GetPciUrlResponse } from "../typings/platformsHostedOnboardingPage/models";
import { DebitAccountHolderRequest, DebitAccountHolderResponse } from "../typings/platformsFund/models";
let client: Client;
let platforms: Platforms;
let scope: nock.Scope;
let accountHolder: A.CreateAccountHolderResponse;
let account: A.CreateAccountResponse;
let accountHolderToSuspend: A.CreateAccountHolderResponse;
let accountToClose: A.CreateAccountResponse;
let accountHolderToUnSuspend: A.CreateAccountHolderResponse;
let accountHolderToClose: A.CreateAccountHolderResponse;
let notificationConfigurationToRetrieve: N.GetNotificationConfigurationResponse;
const generateRandomCode = (): string => Math.floor(Math.random() * Date.now()).toString();
const accountHolderDetails: AccountHolderDetails = {
email: "random_email@example.com",
fullPhoneNumber: "312030291928",
webAddress: "http://example.com",
individualDetails: {
name: {
firstName: "John",
gender: A.ViasName.GenderEnum.Male,
lastName: "Smith"
}
},
address: {
country: "NL"
},
};
const notificationConfigurationDetails: NotificationConfigurationDetails = {
active: true,
notifyURL: "https://www.adyen.com/notification-handler",
eventConfigs: [
{
eventType: "ACCOUNT_HOLDER_VERIFICATION",
includeMode: "INCLUDE"
}
],
sslProtocol: "SSL"
};
const assertError = (e: HttpClientException): void => {
if (e.responseBody?.includes("Account code does not exist or invalid") || e.responseBody?.includes("Failed to retrieve account holder")) {
return;
}
fail(e);
};
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createBasicAuthClient();
client.config.password = process.env.ADYEN_MARKETPLACE_PASSWORD;
client.config.username = process.env.ADYEN_MARKETPLACE_USER;
scope = nock(client.config.marketPayEndpoint!);
platforms = new Platforms(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("Platforms Test", function () {
describe("Account", function(): void {
describe("Accounts", function () {
const cases = [
["closeAccount", createMock<A.CloseAccountRequest>(), createMock<A.CloseAccountResponse>()],
["updateAccount", createMock<A.UpdateAccountRequest>(), createMock<A.UpdateAccountResponse>()],
["createAccount", createMock<A.CreateAccountRequest>(), createMock<A.CreateAccountResponse>()],
["uploadDocument", createMock<A.UploadDocumentRequest>(), createMock<A.GetUploadedDocumentsResponse>()],
["getUploadedDocuments", createMock<A.GetUploadedDocumentsRequest>(), createMock<A.GetUploadedDocumentsResponse>()],
["deleteBankAccounts", createMock<A.DeleteBankAccountRequest>(), createMock<A.GenericResponse>()],
["deletePayoutMethods", createMock<A.DeletePayoutMethodRequest>(), createMock<A.GenericResponse>()],
["deleteShareholders", createMock<A.DeleteShareholderRequest>(), createMock<A.GenericResponse>()],
["checkAccountHolder", createMock<A.PerformVerificationRequest>(), createMock<A.GenericResponse>()],
["createAccountHolder", createMock<A.CreateAccountRequest>(), createMock<A.CreateAccountHolderRequest>()],
["getAccountHolder", createMock<A.GetAccountHolderRequest>(), createMock<A.GetAccountHolderRequest>()],
["updateAccountHolder", createMock<A.UpdateAccountHolderRequest>(), createMock<A.UpdateAccountHolderResponse>()],
["updateAccountHolderState", createMock<A.UpdateAccountHolderStateRequest>(), createMock<A.GetAccountHolderStatusResponse>()],
["suspendAccountHolder", createMock<A.SuspendAccountHolderRequest>(), createMock<A.SuspendAccountHolderResponse>()],
["unSuspendAccountHolder", createMock<A.UnSuspendAccountHolderRequest>(), createMock<A.UnSuspendAccountHolderResponse>()],
["closeAccountHolder", createMock<A.CloseAccountHolderRequest>(), createMock<A.CloseAccountResponse>()],
["getTaxForm", createMock<A.GetTaxFormRequest>(), createMock<A.GetTaxFormResponse>()],
];
test.each(cases)(
"should %p",
async (...args) => {
const service = platforms.Account;
scope.post(`/Account/${Client.MARKETPAY_ACCOUNT_API_VERSION}//${args[0]}`).reply(200, args[2]);
const result = await service[args[0] as string](args[1] as never);
expect(result).toMatchObject(args[2]);
}
);
});
});
describe("Fund", function () {
const cases = [
["accountHolderBalance", createMock<F.AccountHolderBalanceRequest>(), createMock<F.AccountHolderBalanceResponse>()],
["accountHolderTransactionList", createMock<F.AccountHolderTransactionListRequest>(), createMock<F.AccountHolderTransactionListResponse>()],
["payoutAccountHolder", createMock<F.PayoutAccountHolderRequest>(), createMock<F.PayoutAccountHolderResponse>()],
["transferFunds", createMock<F.TransferFundsRequest>(), createMock<F.TransferFundsResponse>()],
["refundFundsTransfer", createMock<F.RefundFundsTransferRequest>(), createMock<F.RefundFundsTransferResponse>()],
["setupBeneficiary", createMock<F.SetupBeneficiaryRequest>(), createMock<F.SetupBeneficiaryResponse>()],
["refundNotPaidOutTransfers", createMock<F.RefundNotPaidOutTransfersRequest>(), createMock<F.RefundNotPaidOutTransfersResponse>()],
["debitAccountHolder", createMock<DebitAccountHolderRequest>(), createMock<DebitAccountHolderResponse>()],
];
test.each(cases)(
"should %p",
async (...args) => {
const fund = platforms.Fund;
scope.post(`/Fund/${Client.MARKETPAY_FUND_API_VERSION}//${args[0]}`).reply(200, args[2]);
const result = await fund[args[0] as string](args[1] as never);
expect(result).toMatchObject(args[2]);
}
);
});
describe("Notification Configuration", function() {
const cases = [
["createNotificationConfiguration", createMock<N.CreateNotificationConfigurationRequest>(), createMock<N.GetNotificationConfigurationResponse>()],
["getNotificationConfiguration", createMock<N.GetNotificationConfigurationRequest>(), createMock<N.GetNotificationConfigurationResponse>()],
["getNotificationConfigurationList", {}, createMock<N.GetNotificationConfigurationListResponse>()],
["testNotificationConfiguration", createMock<N.TestNotificationConfigurationRequest>(), createMock<N.TestNotificationConfigurationResponse>()],
["updateNotificationConfiguration", createMock<N.UpdateNotificationConfigurationRequest>(), createMock<N.GetNotificationConfigurationResponse>()],
["deleteNotificationConfigurations", createMock<N.DeleteNotificationConfigurationRequest>(), createMock<N.GenericResponse>()],
];
test.each(cases)(
"should %p",
async (...args) => {
const notificationConfiguration = platforms.NotificationConfiguration;
scope.post(`/Notification/${Client.MARKETPAY_NOTIFICATION_CONFIGURATION_API_VERSION}//${args[0]}`).reply(200, args[2]);
const result = await notificationConfiguration[args[0] as string](args[1] as never);
expect(result).toMatchObject(args[2]);
}
);
});
describe("Hop", function () {
const cases = [
["getOnboardingUrl", createMock<GetOnboardingUrlRequest>(), createMock<GetOnboardingUrlResponse>()],
["getPciQuestionnaireUrl", createMock<GetPciUrlRequest>(), createMock<GetPciUrlResponse>()],
];
test.each(cases)(
"should %p",
async (...args) => {
const hostedOnboardingPage = platforms.HostedOnboardingPage;
scope.post(`/Hop/${Client.MARKETPAY_HOP_API_VERSION}//${args[0]}`).reply(200, args[2]);
const result = await hostedOnboardingPage[args[0] as string](args[1] as never);
expect(result).toMatchObject(args[2]);
}
);
});
});
describe.skip("Platforms Test E2E", function(): void {
beforeAll(async () => {
accountHolder = await platforms.Account.createAccountHolder({
accountHolderCode: generateRandomCode(),
accountHolderDetails,
legalEntity: A.CreateAccountHolderRequest.LegalEntityEnum.Individual,
});
account = await platforms.Account.createAccount({
accountHolderCode: generateRandomCode(),
description: "This is a new account",
metadata: {meta: "data"},
payoutSchedule: A.CreateAccountRequest.PayoutScheduleEnum.Weekly,
});
accountHolderToSuspend = await platforms.Account.createAccountHolder({
accountHolderCode: generateRandomCode(),
accountHolderDetails,
legalEntity: A.CreateAccountHolderRequest.LegalEntityEnum.Individual,
});
accountToClose = await platforms.Account.createAccount({
accountHolderCode: generateRandomCode(),
description: "This is a new account",
metadata: {meta: "data"},
payoutSchedule: A.CreateAccountRequest.PayoutScheduleEnum.Weekly,
});
accountHolderToUnSuspend = await platforms.Account.createAccountHolder({
accountHolderCode: generateRandomCode(),
accountHolderDetails,
legalEntity: A.CreateAccountHolderRequest.LegalEntityEnum.Individual,
});
await platforms.Account.suspendAccountHolder({ accountHolderCode: accountHolderToUnSuspend.accountHolderCode});
accountHolderToClose = await platforms.Account.createAccountHolder({
accountHolderCode: generateRandomCode(),
accountHolderDetails,
legalEntity: A.CreateAccountHolderRequest.LegalEntityEnum.Individual,
});
notificationConfigurationToRetrieve = await platforms.NotificationConfiguration.createNotificationConfiguration({
configurationDetails: {
...notificationConfigurationDetails,
description: `${generateRandomCode()}`
}
});
});
describe("Account", function(): void {
describe("Accounts E2E", function () {
it("should create account holder", async function() {
nock.restore();
try {
expect(accountHolder.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should get account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.getAccountHolder({
accountHolderCode: accountHolder.accountHolderCode,
});
expect(result.accountHolderDetails.email).toEqual("random_email@example.com");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should update account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.updateAccountHolder({
accountHolderCode: accountHolder.accountHolderCode,
accountHolderDetails: {
...accountHolderDetails,
address: {
country: "BE"
}
}
});
expect(result.accountHolderDetails!.address?.country).toEqual("BE");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should check account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.checkAccountHolder({
accountHolderCode: accountHolder.accountHolderCode,
accountStateType: A.PerformVerificationRequest.AccountStateTypeEnum.Processing,
tier: 2
});
expect(result.resultCode).toEqual("Success");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should create an account", async function() {
nock.restore();
try {
expect(account.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should upload verification document", async function() {
nock.restore();
try {
const result = await platforms.Account.uploadDocument({
documentContent,
documentDetail: {
accountHolderCode: account.accountHolderCode,
documentType: A.DocumentDetail.DocumentTypeEnum.IdCardFront,
description: "test document 000",
filename: "IDCardFront.png"
}
});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should get uploaded verification documents", async function() {
nock.restore();
try {
await platforms.Account.uploadDocument({
documentContent,
documentDetail: {
accountHolderCode: account.accountHolderCode,
documentType: A.DocumentDetail.DocumentTypeEnum.IdCardFront,
description: "test document 000",
filename: "IDCardFront.png"
}
});
const result = await platforms.Account.getUploadedDocuments({
accountHolderCode: account.accountHolderCode,
});
expect(result.documentDetails![0].filename).toEqual("IDCardFront.png");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should close account", async function() {
nock.restore();
try {
const result = await platforms.Account.closeAccount({
accountCode: accountToClose.accountCode
});
expect(result.status).toEqual("Closed");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should suspend account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.suspendAccountHolder({
accountHolderCode: accountHolderToSuspend.accountHolderCode,
});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should unsuspend account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.unSuspendAccountHolder({ accountHolderCode: accountHolderToUnSuspend.accountHolderCode });
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should update account holder state", async function() {
nock.restore();
try {
const result = await platforms.Account.updateAccountHolderState({
accountHolderCode: accountHolder.accountHolderCode,
disable: false,
stateType: A.UpdateAccountHolderStateRequest.StateTypeEnum.Payout
});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should close account holder", async function() {
nock.restore();
try {
const result = await platforms.Account.closeAccountHolder({
accountHolderCode: accountHolderToClose.accountHolderCode
});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should get tax form", async function() {
nock.restore();
try {
const result = await platforms.Account.getTaxForm({
accountHolderCode: accountHolder.accountHolderCode,
formType: "1099-K",
year: 2020
});
expect(result.content).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
});
});
describe("Fund", function () {
it("should retrieve the balance of an account holder", async function() {
nock.restore();
try {
const result = await platforms.Fund.accountHolderBalance({
accountHolderCode: generateRandomCode()
});
expect(result.balancePerAccount![0].detailBalance).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should retrieve a list of transaction for an account holder's accounts", async function() {
nock.restore();
try {
const result = await platforms.Fund.accountHolderTransactionList({
accountHolderCode: generateRandomCode()
});
expect(result.accountTransactionLists![0].transactions).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should transfer funds between two accounts", async function() {
nock.restore();
try {
const result = await platforms.Fund.transferFunds({
sourceAccountCode: "8515883280985939",
destinationAccountCode: "8815883278206345",
amount: {
currency: "EUR",
value: 1
},
transferCode: "SUBSCRIPTION"
});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
});
describe("Notification Configuration", function () {
let configurationID: number;
it("should retrieve all Notification Configurations", async function() {
nock.restore();
try {
const result = await platforms.NotificationConfiguration.getNotificationConfigurationList({});
const resultStr = JSON.stringify(result);
expect(resultStr.includes("pspReference")).toBeTruthy();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should create a Notification Configuration", async function() {
nock.restore();
try {
const result = await platforms.NotificationConfiguration.createNotificationConfiguration({
configurationDetails: {
...notificationConfigurationDetails,
description: `${generateRandomCode()}`
}
});
expect(result.configurationDetails.active).toBeTruthy();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should retrieve a Notification Configuration", async function() {
nock.restore();
try {
configurationID = notificationConfigurationToRetrieve.configurationDetails.notificationId!;
const result = await platforms.NotificationConfiguration.getNotificationConfiguration({
notificationId: configurationID
});
expect(result.configurationDetails.notifyURL).toEqual("https://www.adyen.com/notification-handler");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should update a Notification Configuration", async function() {
nock.restore();
try {
const result = await platforms.NotificationConfiguration.updateNotificationConfiguration({
configurationDetails: {
eventConfigs: [
{
eventType: "ACCOUNT_HOLDER_VERIFICATION",
includeMode: "EXCLUDE"
},
{
"eventType": "ACCOUNT_CREATED",
"includeMode": "INCLUDE"
}
],
notifyURL: "https://www.adyen.com/notification-handler",
notificationId: configurationID
}
});
const accountHolderVerification = result.configurationDetails.eventConfigs.filter(event => event.eventType === "ACCOUNT_HOLDER_VERIFICATION")[0];
expect(accountHolderVerification.includeMode).toEqual("EXCLUDE");
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
it("should delete a Notification Configuration", async function() {
nock.restore();
const notificationIds = [];
notificationIds.push(configurationID);
try {
const result = await platforms.NotificationConfiguration.deleteNotificationConfigurations({notificationIds});
expect(result.pspReference).toBeDefined();
} catch (e) {
if(e instanceof HttpClientException) {
assertError(e);
} else {
fail();
}
}
});
});
});

View File

@@ -1,174 +1,49 @@
import nock from "nock";
import { createClient } from "../__mocks__/base";
import { disableSuccess } from "../__mocks__/recurring/disableSuccess";
import { listRecurringDetailsSuccess } from "../__mocks__/recurring/listRecurringDetailsSuccess";
import { notifyShopperSuccess } from "../__mocks__/recurring/notifyShopperSuccess";
import RecurringService from "../services/recurring";
import {createMockClientFromResponse} from "../__mocks__/base";
import {disableSuccess} from "../__mocks__/recurring/disableSuccess";
import {listRecurringDetailsSuccess} from "../__mocks__/recurring/listRecurringDetailsSuccess";
import Recurring from "../services/recurring";
import Client from "../client";
import { recurring } from "../typings";
import {Permit} from "../typings/recurring/permit";
import {CreatePermitRequest} from "../typings/recurring/createPermitRequest";
import {ObjectSerializer} from "../typings/recurring/models";
const createRecurringDetailsRequest = (): recurring.RecurringDetailsRequest => {
const createRecurringDetailsRequest = (): IRecurring.RecurringDetailsRequest => {
return {
merchantAccount: process.env.ADYEN_MERCHANT!,
recurring: { contract: recurring.Recurring.ContractEnum.Recurring },
shopperReference: "shopperReference",
merchantAccount: "MerchantAccount",
recurring: { contract: "ONECLICK" },
shopperReference: "test-123",
};
};
let client: Client;
let recurringService: RecurringService;
let recurring: Recurring;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
recurringService = new RecurringService(client);
client = createMockClientFromResponse();
recurring = new Recurring(client);
scope = nock(`${client.config.endpoint}/pal/servlet/Recurring/${Client.RECURRING_API_VERSION}`);
});
afterEach(() => {
nock.cleanAll();
});
describe("Recurring", (): void => {
test("should list recurring details", async (): Promise<void> => {
it("should test have recurring details list", async (): Promise<void> => {
scope.post("/listRecurringDetails")
.reply(200, listRecurringDetailsSuccess);
const request = createRecurringDetailsRequest();
const result = await recurringService.listRecurringDetails(request);
expect(result).toBeTruthy();
expect(result.details?.[0].recurringDetailReference).toBe("recurringReference");
const result = await recurring.listRecurringDetails(request);
expect(result).toEqual(listRecurringDetailsSuccess);
});
test("should disable", async (): Promise<void> => {
it("should disable", async (): Promise<void> => {
scope.post("/disable")
.reply(200, disableSuccess);
const request: recurring.DisableRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
shopperReference: "shopperReference",
recurringDetailReference: "recurring.recurringDetailReference",
const request: IRecurring.DisableRequest = {
merchantAccount: "MerchantAccount",
recurringDetailReference: "reference",
shopperReference: "test-123",
};
try {
const result = await recurringService.disable(request);
expect(result).toBeTruthy();
} catch (e) {
fail(e);
}
});
test("should send pre-debit Notification", async (): Promise<void> => {
scope.post("/notifyShopper")
.reply(200, notifyShopperSuccess);
const notifyShopperRequest: recurring.NotifyShopperRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
shopperReference: "shopperReference",
storedPaymentMethodId: "8415995487234100",
amount: {
currency: "INR",
value: 1000
},
billingDate: "2021-03-16",
reference: "Example reference",
displayedReference: "Example displayed reference"
};
try {
const result = await recurringService.notifyShopper(notifyShopperRequest);
expect(result).toBeTruthy();
} catch (e) {
fail(e);
}
});
test("should schedule account updater", async (): Promise<void> => {
const scheduleAccountUpdaterSuccess: recurring.ScheduleAccountUpdaterResult = {
pspReference: "mocked_psp",
result: "SUCCESS"
};
scope.post("/scheduleAccountUpdater")
.reply(200, scheduleAccountUpdaterSuccess);
const request: recurring.ScheduleAccountUpdaterRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
reference: "ref",
card: {
expiryMonth: "03",
expiryYear: "2030",
holderName: "John Smith",
number: "4111111111111111"
}
};
try {
const result = await recurringService.scheduleAccountUpdater(request);
expect(result).toBeTruthy();
} catch (e) {
fail(e);
}
});
test("should do a createPermit request", async (): Promise<void> => {
const createPermitResultSuccess: recurring.CreatePermitResult = {
pspReference: "1234567890"
};
scope.post("/createPermit")
.reply(200, createPermitResultSuccess);
const permit: Permit = {
validTillDate: new Date("2022-03-25"),
partnerId: "partnerID"
};
const request: recurring.CreatePermitRequest = {
permits: [permit],
merchantAccount: process.env.ADYEN_MERCHANT!,
shopperReference: "shopperRef",
recurringDetailReference: "recurringRef",
};
const serializedRequest: CreatePermitRequest = ObjectSerializer.serialize(request, "CreatePermitRequest");
expect(serializedRequest.permits[0].validTillDate?.toString()).toBe("2022-03-25T00:00:00.000Z");
try {
const result = await recurringService.createPermit(request);
expect(result).toBeTruthy();
} catch (e) {
fail(e);
}
});
test("should do a disablePermit request", async (): Promise<void> => {
const disablePermitResultSuccess: recurring.DisablePermitResult = {
pspReference: "1234567890",
status: "disabled",
};
scope.post("/disablePermit")
.reply(200, disablePermitResultSuccess);
const request: recurring.DisablePermitRequest = {
merchantAccount: process.env.ADYEN_MERCHANT!,
token: "permitToken"
};
try {
const result = await recurringService.disablePermit(request);
expect(result).toBeTruthy();
} catch (e) {
fail(e);
}
const result = await recurring.disable(request);
expect(result).toEqual(disableSuccess);
});
});

View File

@@ -1,255 +0,0 @@
import nock from "nock";
import Client from "../client";
import {createClient} from "../__mocks__/base";
import {StoredValue} from "../services";
import { storedValue } from "../typings";
let client: Client;
let storedValueService: StoredValue;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.storedValueEndpoint}/${Client.STOREDVALUE_API_VERSION}`);
storedValueService = new StoredValue(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("StoredValue", (): void => {
test("Should issue Givex card", async (): Promise<void> => {
scope.post("/issue")
.reply(200, {
"currentBalance": {
"currency": "EUR",
"value": 1000
},
"pspReference": "851564651069192J",
"resultCode": "Success",
"paymentMethod": {
"number": "7219627091701347",
"securityCode": "0140",
"type": "givex"
}
});
const issueRequest: storedValue.StoredValueIssueRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store": "YOUR_STORE_ID",
"paymentMethod": {
"type": "givex"
},
"amount": {
"currency": "EUR",
"value": 1000
},
"reference": "YOUR_REFERENCE"
};
const issueResponse: storedValue.StoredValueIssueResponse = await storedValueService.issue(issueRequest);
expect(issueResponse.pspReference).toEqual("851564651069192J");
});
test("Should issue virtual Fiserv card", async (): Promise<void> => {
scope.post("/issue")
.reply(200, {
"currentBalance": {
"currency": "EUR",
"value": 1000
},
"pspReference": "851564651069192J",
"resultCode": "Success",
"paymentMethod": {
"number": "7219627091701347",
"securityCode": "0140",
"type": "givex"
}
});
const issueRequest: storedValue.StoredValueIssueRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store": "YOUR_STORE_ID",
"paymentMethod": {
"type": "valuelink"
},
// "giftCardPromoCode": "1324",
"reference": "YOUR_REFERENCE"
};
const issueResponse: storedValue.StoredValueIssueResponse = await storedValueService.issue(issueRequest);
expect(issueResponse.pspReference).toEqual("851564651069192J");
});
test("Should activate card", async (): Promise<void> => {
scope.post("/changeStatus")
.reply(200, {
"currentBalance": {
"currency": "USD",
"value": 1000
},
"pspReference": "851564652149588K",
"resultCode": "Success"
});
const statusRequest: storedValue.StoredValueStatusChangeRequest = {
"status": storedValue.StoredValueStatusChangeRequest.StatusEnum.Active,
"amount": {
"currency": "USD",
"value": 1000
},
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store":"YOUR_STORE_ID",
"paymentMethod": {
"type": "svs",
"number": "6006491286999921374",
"securityCode": "1111"
},
"reference": "YOUR_REFERENCE"
};
const changeStatusResponse: storedValue.StoredValueStatusChangeResponse = await storedValueService.changeStatus(statusRequest);
expect(changeStatusResponse.pspReference).toEqual("851564652149588K");
});
test("Should deactivate card", async (): Promise<void> => {
scope.post("/changeStatus")
.reply(200, {
"currentBalance": {
"currency": "USD",
"value": 1000
},
"pspReference": "851564652149588K",
"resultCode": "Success"
});
const statusRequest: storedValue.StoredValueStatusChangeRequest = {
"status": storedValue.StoredValueStatusChangeRequest.StatusEnum.Inactive,
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store":"YOUR_STORE_ID",
"paymentMethod": {
"type": "givex",
},
"recurringDetailReference": "7219627091701347",
"shopperReference": "YOUR_UNIQUE_SHOPPER_ID_P3fW3k9D2tvXFu6l",
"shopperInteraction": storedValue.StoredValueStatusChangeRequest.ShopperInteractionEnum.Ecommerce,
"reference": "YOUR_REFERENCE"
};
const changeStatusResponse: storedValue.StoredValueStatusChangeResponse = await storedValueService.changeStatus(statusRequest);
expect(changeStatusResponse.pspReference).toEqual("851564652149588K");
});
test("Should load funds to card", async (): Promise<void> => {
scope.post("/load")
.reply(200, {
"currentBalance": {
"currency": "USD",
"value": 30000
},
"pspReference": "851564654294247B",
"resultCode": "Success"
});
const loadRequest: storedValue.StoredValueLoadRequest = {
"amount": {
"currency": "USD",
"value": 2000
},
"loadType": storedValue.StoredValueLoadRequest.LoadTypeEnum.MerchandiseReturn,
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store":"YOUR_STORE_ID",
"paymentMethod": {
"type": "svs",
"number": "6006491286999921374",
"securityCode": "1111"
},
"reference": "YOUR_REFERENCE"
};
const loadResponse: storedValue.StoredValueLoadResponse = await storedValueService.load(loadRequest);
expect(loadResponse.pspReference).toEqual("851564654294247B");
});
test("Should check remaining balance of card", async (): Promise<void> => {
scope.post("/checkBalance")
.reply(200, {
"currentBalance": {
"currency": "EUR",
"value": 5600
},
"pspReference": "881564657480267D",
"resultCode": "Success"
});
const checkBalanceRequest: storedValue.StoredValueBalanceCheckRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store":"YOUR_STORE_ID",
"paymentMethod": {
"type": "svs",
"number": "603628672882001915092",
"securityCode": "5754"
},
"reference": "YOUR_REFERENCE"
};
const checkBalanceResponse: storedValue.StoredValueBalanceCheckResponse = await storedValueService.checkBalance(checkBalanceRequest);
expect(checkBalanceResponse.pspReference).toEqual("881564657480267D");
});
test("Should transfer full value from one card to another", async (): Promise<void> => {
scope.post("/mergeBalance")
.reply(200, {
"currentBalance": {
"currency": "EUR",
"value": 5600
},
"pspReference": "881564657480267D",
"resultCode": "Success"
});
const mergeBalanceRequest: storedValue.StoredValueBalanceMergeRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"store":"YOUR_STORE_ID",
"sourcePaymentMethod": {
"number": "7777182708544835",
"securityCode": "2329"
},
"paymentMethod": {
"type": "valuelink",
"number": "8888182708544836",
"securityCode": "2330"
},
"reference": "YOUR_REFERENCE"
};
const mergeBalanceResponse: storedValue.StoredValueBalanceMergeResponse = await storedValueService.mergebalance(mergeBalanceRequest);
expect(mergeBalanceResponse.pspReference).toEqual("881564657480267D");
});
test("Should undo transaction on card", async (): Promise<void> => {
scope.post("/voidTransaction")
.reply(200, {
"currentBalance": {
"currency": "EUR",
"value": 120000
},
"pspReference": "851564673300692A",
"resultCode": "Success"
});
const voidTransactionRequest: storedValue.StoredValueVoidRequest = {
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"originalReference": "851564654294247B",
"reference": "YOUR_REFERENCE"
};
const voidTransactionResponse: storedValue.StoredValueVoidResponse = await storedValueService.voidTransaction(voidTransactionRequest);
expect(voidTransactionResponse.pspReference).toEqual("851564673300692A");
});
});

View File

@@ -1,32 +1,24 @@
import nock from "nock";
import { createClient, createTerminalAPIPaymentRequest, createTerminalAPIRefundRequest } from "../__mocks__/base";
import { asyncRes } from "../__mocks__/terminalApi/async";
import { syncRefund, syncRes, syncResEventNotification } from "../__mocks__/terminalApi/sync";
import {createMockClientFromResponse, createTerminalAPIPaymentRequest} from "../__mocks__/base";
import {asyncRes} from "../__mocks__/terminalApi/async";
import {syncRes} from "../__mocks__/terminalApi/sync";
import Client from "../client";
import TerminalCloudAPI from "../services/terminalCloudAPI";
import { terminal} from "../typings";
import {Convert, TerminalApiResponse} from "../typings/terminal";
let client: Client;
let terminalCloudAPI: TerminalCloudAPI;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient(process.env.ADYEN_TERMINAL_APIKEY);
client.config.merchantAccount = process.env.ADYEN_TERMINAL_MERCHANT;
client = createMockClientFromResponse();
terminalCloudAPI = new TerminalCloudAPI(client);
scope = nock(`${client.config.terminalApiCloudEndpoint}`);
});
afterEach((): void => {
nock.cleanAll();
});
describe("Terminal Cloud API", (): void => {
test("should make an async payment request", async (): Promise<void> => {
it("should make an async payment request", async (): Promise<void> => {
scope.post("/async").reply(200, asyncRes);
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
@@ -36,45 +28,13 @@ describe("Terminal Cloud API", (): void => {
expect(requestResponse).toEqual("ok");
});
test("should make a sync payment request", async (): Promise<void> => {
scope.post("/sync").reply(200, syncRes);
it("should make a sync payment request", async (): Promise<void> => {
const response = Convert.toTerminalApiResponse(syncRes);
scope.post("/sync").reply(200, response);
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
const terminalAPIResponse: terminal.TerminalApiResponse = await terminalCloudAPI.sync(terminalAPIPaymentRequest);
const terminalAPIResponse: TerminalApiResponse = await terminalCloudAPI.sync(terminalAPIPaymentRequest);
expect(terminalAPIResponse.SaleToPOIResponse?.PaymentResponse).toBeDefined();
expect(terminalAPIResponse.SaleToPOIResponse?.MessageHeader).toBeDefined();
expect(terminalAPIResponse).toEqual(response);
});
test("should return event notification if response contains it", async (): Promise<void> => {
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
scope.post("/sync").reply(200, syncResEventNotification);
const terminalAPIResponse = await terminalCloudAPI.sync(terminalAPIPaymentRequest);
expect(terminalAPIResponse.SaleToPOIRequest?.EventNotification).toBeDefined();
});
test("should make an async refund request", async (): Promise<void> => {
scope.post("/sync").reply(200, syncRes);
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
const terminalAPIResponse: terminal.TerminalApiResponse = await terminalCloudAPI.sync(terminalAPIPaymentRequest);
const pOITransactionId = terminalAPIResponse.SaleToPOIResponse!.PaymentResponse!.POIData!.POITransactionID;
expect(pOITransactionId).toBeTruthy();
scope.post("/sync").reply(200, syncRefund);
const terminalAPIRefundRequest = createTerminalAPIRefundRequest(pOITransactionId);
const id = Math.floor(Math.random() * Math.floor(10000000)).toString();
terminalAPIRefundRequest.SaleToPOIRequest.MessageHeader.ServiceID = id;
const saleToAcquirerData: terminal.SaleToAcquirerData = new terminal.SaleToAcquirerData();
saleToAcquirerData.currency = "EUR";
terminalAPIRefundRequest.SaleToPOIRequest.ReversalRequest!.SaleData!.SaleToAcquirerData = saleToAcquirerData;
const terminalAPIRefundResponse = await terminalCloudAPI.sync(terminalAPIRefundRequest);
expect(terminalAPIRefundResponse.SaleToPOIResponse?.ReversalResponse?.Response.Result).toBe("Success");
}, 20000);
});

View File

@@ -1,9 +1,9 @@
import nock from "nock";
import { createClient, createTerminalAPIPaymentRequest } from "../__mocks__/base";
import { localEncRes, wrongEncRes } from "../__mocks__/terminalApi/local";
import {createMockClientFromResponse, createTerminalAPIPaymentRequest} from "../__mocks__/base";
import {localEncRes, localSecuredRes, wrongEncRes} from "../__mocks__/terminalApi/local";
import Client from "../client";
import TerminalLocalAPI from "../services/terminalLocalAPI";
import { terminal } from "../typings";
import {Convert, SecurityKey, TerminalApiResponse} from "../typings/terminal";
import NexoCryptoException from "../services/exception/nexoCryptoException";
let client: Client;
@@ -11,58 +11,50 @@ let terminalLocalAPI: TerminalLocalAPI;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
client = createMockClientFromResponse();
terminalLocalAPI = new TerminalLocalAPI(client);
scope = nock(client.config.terminalApiLocalEndpoint + ":8443/nexo");
});
afterEach((): void => {
nock.cleanAll();
});
describe("Terminal Local API", (): void => {
test("should make a local payment", async (): Promise<void> => {
scope.post("/").reply(200, localEncRes);
it("should make a local payment", async (): Promise<void> => {
const securedResponse = Convert.toTerminalApiSecuredResponse(localEncRes);
const response = Convert.toTerminalApiResponse(localSecuredRes);
scope.post("/").reply(200, securedResponse);
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
const securityKey: terminal.SecurityKey = {
AdyenCryptoVersion: 0,
KeyIdentifier: "CryptoKeyIdentifier12345",
KeyVersion: 0,
Passphrase: "p@ssw0rd123456",
const securityKey: SecurityKey = {
adyenCryptoVersion: 1,
keyIdentifier: "CryptoKeyIdentifier12345",
keyVersion: 1,
passphrase: "p@ssw0rd123456",
};
const terminalApiResponse: terminal.TerminalApiResponse =
const terminalApiResponse: TerminalApiResponse =
await terminalLocalAPI.request(terminalAPIPaymentRequest, securityKey);
expect(terminalApiResponse.SaleToPOIResponse?.PaymentResponse).toBeDefined();
expect(terminalApiResponse.SaleToPOIResponse?.MessageHeader).toBeDefined();
expect(response).toEqual(terminalApiResponse);
});
test("should return NexoCryptoException", async (): Promise<void> => {
scope.post("/").reply(200, wrongEncRes);
it("should return NexoCryptoException", async (): Promise<void> => {
const securedResponse = Convert.toTerminalApiSecuredResponse(wrongEncRes);
scope.post("/").reply(200, securedResponse);
const terminalAPIPaymentRequest = createTerminalAPIPaymentRequest();
const securityKey: terminal.SecurityKey = {
AdyenCryptoVersion: 0,
KeyIdentifier: "CryptoKeyIdentifier12345",
KeyVersion: 0,
Passphrase: "p@ssw0rd123456",
const securityKey: SecurityKey = {
adyenCryptoVersion: 1,
keyIdentifier: "CryptoKeyIdentifier12345",
keyVersion: 1,
passphrase: "p@ssw0rd123456",
};
try {
await terminalLocalAPI.request(terminalAPIPaymentRequest, securityKey);
} catch (e) {
if(e instanceof NexoCryptoException) {
expect(e.message).toEqual("Hmac validation failed");
} else {
fail();
}
expect(e instanceof NexoCryptoException);
expect(e.message).toEqual("Hmac validation failed");
}
});
});

View File

@@ -1,146 +0,0 @@
import nock from "nock";
import Client from "../client";
import { createClient } from "../__mocks__/base";
import TerminalManagement from "../services/terminalManagement";
import { terminalManagement } from "../typings";
let client: Client;
let terminalManagementService: TerminalManagement;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
scope = nock(`${client.config.terminalManagementEndpoint}/${Client.TERMINAL_MANAGEMENT_API_VERSION}`);
terminalManagementService = new TerminalManagement(client);
});
afterEach(() => {
nock.cleanAll();
});
describe("POS Terminal Management API", (): void => {
test("Should support /assignTerminals", async (): Promise<void> => {
scope.post("/assignTerminals")
.reply(200, {
"results": {
"P400Plus-275479597": "RemoveConfigScheduled"
}
});
const request: terminalManagement.AssignTerminalsRequest = {
"companyAccount": "YOUR_COMPANY_ACCOUNT",
"terminals": [
"P400Plus-275479597"
]
};
const response: terminalManagement.AssignTerminalsResponse = await terminalManagementService.assignTerminals(request);
expect(response.results["P400Plus-275479597"]).toEqual("RemoveConfigScheduled");
});
test("Should support /findTerminal", async (): Promise<void> => {
scope.post("/findTerminal")
.reply(200, {
"companyAccount": "YOUR_COMPANY_ACCOUNT",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"merchantInventory": false,
"terminal": "P400Plus-275479597"
});
const request: terminalManagement.FindTerminalRequest = {
"terminal": "P400Plus-275479597"
};
const response: terminalManagement.FindTerminalResponse = await terminalManagementService.findTerminal(request);
expect(response.terminal).toEqual("P400Plus-275479597");
});
test("Should support /getStoresUnderAccount", async (): Promise<void> => {
scope.post("/getStoresUnderAccount")
.reply(200, {
"stores": [
{
"store": "YOUR_STORE",
"description": "YOUR_STORE",
"address": {
"city": "The City",
"countryCode": "NL",
"postalCode": "1234",
"streetAddress": "The Street"
},
"status": "Active",
"merchantAccountCode": "YOUR_MERCHANT_ACCOUNT"
}
]
});
const request: terminalManagement.GetStoresUnderAccountRequest = {
"companyAccount": "YOUR_COMPANY_ACCOUNT"
};
const response: terminalManagement.GetStoresUnderAccountResponse = await terminalManagementService.getStoresUnderAccount(request);
expect(response.stores).toHaveLength(1);
expect(response.stores![0].status).toEqual("Active");
expect(response.stores![0].address?.countryCode).toEqual("NL");
});
test("Should support /getTerminalDetails", async (): Promise<void> => {
scope.post("/getTerminalDetails")
.reply(200, {
"companyAccount": "YOUR_COMPANY_ACCOUNT",
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"merchantInventory": false,
"terminal": "P400Plus-275479597",
"deviceModel": "P400Plus",
"serialNumber": "275-479-597",
"permanentTerminalId": "75479597",
"terminalStatus": "ReAssignToInventoryPending",
"firmwareVersion": "Verifone_VOS 1.57.6",
"country": "NETHERLANDS",
"dhcpEnabled": false
});
const request: terminalManagement.GetTerminalDetailsRequest = {
"terminal": "P400Plus-275479597"
};
const response: terminalManagement.GetTerminalDetailsResponse = await terminalManagementService.getTerminalDetails(request);
expect(response.deviceModel).toBe("P400Plus");
});
test("Should support /getTerminalsUnderAccount", async (): Promise<void> => {
scope.post("/getTerminalsUnderAccount")
.reply(200, {
"companyAccount": "YOUR_COMPANY_ACCOUNT",
"merchantAccounts": [
{
"merchantAccount": "YOUR_MERCHANT_ACCOUNT",
"inStoreTerminals": [
"P400Plus-275479597"
],
"stores": [
{
"store": "YOUR_STORE",
"inStoreTerminals": [
"M400-401972715"
]
}
]
}
]
});
const request: terminalManagement.GetTerminalsUnderAccountRequest = {
"companyAccount": "YOUR_COMPANY_ACCOUNT"
};
const response: terminalManagement.GetTerminalsUnderAccountResponse = await terminalManagementService.getTerminalsUnderAccount(request);
expect(response.merchantAccounts).toHaveLength(1);
expect(response.merchantAccounts![0].stores).toHaveLength(1);
expect(response.merchantAccounts![0].stores![0].inStoreTerminals).toEqual(["M400-401972715"]);
});
});

View File

@@ -1,68 +0,0 @@
import nock from "nock";
import { createClient } from "../__mocks__/base";
import { transfersSuccess, getTransactionSuccess, listTransactionsSuccess } from "../__mocks__/transfers/responses";
import Client from "../client";
import { Transfers } from "../services";
import { transfer} from "../typings";
let client: Client;
let transferService: Transfers;
let scope: nock.Scope;
beforeEach((): void => {
if (!nock.isActive()) {
nock.activate();
}
client = createClient();
transferService = new Transfers(client);
scope = nock(`https://balanceplatform-api-test.adyen.com/btl/${Client.TRANSFERS_API_VERSION}`);
});
afterEach(() => {
nock.cleanAll();
});
describe("Transfers", (): void => {
test("should transfer fund", async (): Promise<void> => {
scope.post("/transfers")
.reply(200, transfersSuccess);
const request = new transfer.TransferInfo();
request.amount = { currency: "EUR", value: 1000};
request.category = transfer.TransferInfo.CategoryEnum.Bank;
request.counterparty = {
balanceAccountId: "123",
transferInstrumentId: "transfer_id",
bankAccount: {
accountHolder: {
fullName: "Wally Bizzle"
},
accountIdentification: {
iban: "NLRABO12321",
type: transfer.IbanAccountIdentification.TypeEnum.Iban
}
},
};
const response: transfer.Transfer = await transferService.transfers(request);
expect(response.id).toEqual("1W1UG35U8A9J5ZLG");
});
test("should get transaction", async (): Promise<void> => {
scope.get("/transactions/123")
.reply(200, getTransactionSuccess);
const response: transfer.Transaction = await transferService.getTransaction("123");
expect(response.id).toEqual("IZK7C25U7DYVX03Y");
});
test("should list transactions", async (): Promise<void> => {
scope.get("/transactions")
.reply(200, listTransactionsSuccess);
const response: transfer.TransactionSearchResponse = await transferService.listTransactions();
expect(response.data?.length).toEqual(3);
if(response.data && response.data?.length > 0) {
expect(response?.data[0]?.id).toEqual("1VVF0D5U66PIUIVP");
} else {
fail();
}
});
});

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

View File

@@ -1,15 +1,32 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
*
* Adyen NodeJS API Library
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import Config from "./config";
import HttpURLConnectionClient from "./httpClient/httpURLConnectionClient";
import { version } from "../package.json";
import {version} from "../package.json";
import ClientInterface from "./httpClient/clientInterface";
type ClientParametersOverload =
| { config: Config }
| { config: Config; httpClient: ClientInterface }
| { username: string; password: string; environment: Environment}
| { username: string; password: string; environment: Environment; httpClient: ClientInterface }
| { username: string; password: string; environment: Environment; liveEndpointUrlPrefix: string }
| { username: string; password: string; environment: Environment; liveEndpointUrlPrefix: string; httpClient: ClientInterface }
| { username: string; password: string; environment: Environment; applicationName: string }
| { username: string; password: string; environment: Environment; applicationName: string; httpClient: ClientInterface }
| { username: string; password: string; environment: Environment; applicationName: string; liveEndpointUrlPrefix: string }
@@ -37,48 +54,22 @@ class Client {
public static HPP_LIVE = "https://live.adyen.com/hpp";
public static MARKETPAY_ENDPOINT_TEST = "https://cal-test.adyen.com/cal/services";
public static MARKETPAY_ENDPOINT_LIVE = "https://cal-live.adyen.com/cal/services";
public static CHECKOUT_API_VERSION = "v69";
public static API_VERSION = "v68";
public static RECURRING_API_VERSION = "v68";
public static MARKETPAY_ACCOUNT_API_VERSION = "v6";
public static MARKETPAY_FUND_API_VERSION = "v6";
public static MARKETPAY_HOP_API_VERSION = "v6";
public static API_VERSION = "v51";
public static RECURRING_API_VERSION = "v49";
public static MARKETPAY_ACCOUNT_API_VERSION = "v5";
public static MARKETPAY_FUND_API_VERSION = "v5";
public static MARKETPAY_NOTIFICATION_API_VERSION = "v5";
public static MARKETPAY_NOTIFICATION_CONFIGURATION_API_VERSION = "v6";
public static PAYMENT_API_VERSION = "v68";
public static STOREDVALUE_API_VERSION = "v46";
public static TERMINAL_MANAGEMENT_API_VERSION = "v1";
public static MANAGEMENT_API_VERSION = "v1";
public static LIB_NAME = "adyen-node-api-library";
public static LIB_VERSION: string = version;
public static CHECKOUT_ENDPOINT_TEST = "https://checkout-test.adyen.com/checkout";
public static CHECKOUT_ENDPOINT_LIVE_SUFFIX = "-checkout-live.adyenpayments.com/checkout";
public static CHECKOUT_API_VERSION = "v51";
public static BIN_LOOKUP_PAL_SUFFIX = "/pal/servlet/BinLookup/";
public static BIN_LOOKUP_API_VERSION = "v50";
public static CHECKOUT_UTILITY_API_VERSION = "v1";
public static TERMINAL_API_ENDPOINT_TEST = "https://terminal-api-test.adyen.com";
public static TERMINAL_API_ENDPOINT_LIVE = "https://terminal-api-live.adyen.com";
public static ENDPOINT_PROTOCOL = "https://";
public static PAYMENT_API_ENDPOINT_TEST = "https://pal-test.adyen.com/pal/servlet/Payment";
public static PAYMENT_API_ENDPOINT_LIVE = "https://pal-live.adyen.com/pal/servlet/Payment";
public static STOREDVALUE_API_ENDPOINT_TEST = "https://pal-test.adyen.com/pal/servlet/StoredValue";
public static STOREDVALUE_API_ENDPOINT_LIVE = "https://pal-live.adyen.com/pal/servlet/StoredValue";
public static TERMINAL_MANAGEMENT_API_ENDPOINT_TEST = "https://postfmapi-test.adyen.com/postfmapi/terminal";
public static TERMINAL_MANAGEMENT_API_ENDPOINT_LIVE = "https://postfmapi-live.adyen.com/postfmapi/terminal";
public static MANAGEMENT_API_ENDPOINT_TEST = "https://management-test.adyen.com";
public static MANAGEMENT_API_ENDPOINT_LIVE = "https://management-live.adyen.com";
public static BALANCE_PLATFORM_API_VERSION = "v2";
public static BALANCE_PLATFORM_API_ENDPOINT_TEST = "https://balanceplatform-api-test.adyen.com/bcl";
public static BALANCE_PLATFORM_API_ENDPOINT_LIVE = "https://balanceplatform-api-live.adyen.com/bcl";
public static LEGAL_ENTITY_MANAGEMENT_API_VERSION = "v2";
public static LEGAL_ENTITY_MANAGEMENT_API_ENDPOINT_TEST = "https://kyc-test.adyen.com/lem";
public static LEGAL_ENTITY_MANAGEMENT_API_ENDPOINT_LIVE = "https://kyc-live.adyen.com/lem";
public static TRANSFERS_API_VERSION = "v3";
public static TRANSFERS_API_ENDPOINT_TEST = "https://balanceplatform-api-test.adyen.com/btl";
public static TRANSFERS_API_ENDPOINT_LIVE = "https://balanceplatform-api-live.adyen.com/btl";
public static DATA_PROTECTION_API_VERSION = "v1";
public static DATA_PROTECTION_API_ENDPOINT_TEST = "https://ca-test.adyen.com/ca/services/DataProtectionService";
public static DATA_PROTECTION_API_ENDPOINT_LIVE = "https://ca-live.adyen.com/ca/services/DataProtectionService";
private _httpClient!: ClientInterface;
public config: Config;
@@ -94,12 +85,10 @@ class Client {
const environment = options.environment || this.config.environment;
if (environment) {
this.setEnvironment(environment, options.liveEndpointUrlPrefix);
if (options.username && options.password) {
if (options.username && options.password && options.applicationName) {
this.config.username = options.username;
this.config.password = options.password;
if(options.applicationName) {
this.config.applicationName = options.applicationName;
}
this.config.applicationName = options.applicationName;
}
if (options.apiKey) {
@@ -119,28 +108,10 @@ class Client {
this.config.hppEndpoint = Client.HPP_TEST;
this.config.checkoutEndpoint = Client.CHECKOUT_ENDPOINT_TEST;
this.config.terminalApiCloudEndpoint = Client.TERMINAL_API_ENDPOINT_TEST;
this.config.paymentEndpoint = Client.PAYMENT_API_ENDPOINT_TEST;
this.config.storedValueEndpoint = Client.STOREDVALUE_API_ENDPOINT_TEST;
this.config.terminalManagementEndpoint = Client.TERMINAL_MANAGEMENT_API_ENDPOINT_TEST;
this.config.managementEndpoint = Client.MANAGEMENT_API_ENDPOINT_TEST;
this.config.balancePlatformEndpoint = Client.BALANCE_PLATFORM_API_ENDPOINT_TEST;
this.config.legalEntityManagementEndpoint = Client.LEGAL_ENTITY_MANAGEMENT_API_ENDPOINT_TEST;
this.config.transfersEndpoint = Client.TRANSFERS_API_ENDPOINT_TEST;
this.config.dataProtectionEndpoint = Client.DATA_PROTECTION_API_ENDPOINT_TEST;
} else if (environment === "LIVE") {
this.config.endpoint = Client.ENDPOINT_LIVE;
this.config.marketPayEndpoint = Client.MARKETPAY_ENDPOINT_LIVE;
this.config.hppEndpoint = Client.HPP_LIVE;
this.config.terminalApiCloudEndpoint = Client.TERMINAL_API_ENDPOINT_LIVE;
this.config.paymentEndpoint = Client.PAYMENT_API_ENDPOINT_LIVE;
this.config.storedValueEndpoint = Client.STOREDVALUE_API_ENDPOINT_LIVE;
this.config.terminalManagementEndpoint = Client.TERMINAL_MANAGEMENT_API_ENDPOINT_LIVE;
this.config.managementEndpoint = Client.MANAGEMENT_API_ENDPOINT_LIVE;
this.config.balancePlatformEndpoint = Client.BALANCE_PLATFORM_API_ENDPOINT_LIVE;
this.config.legalEntityManagementEndpoint = Client.LEGAL_ENTITY_MANAGEMENT_API_ENDPOINT_LIVE;
this.config.transfersEndpoint = Client.TRANSFERS_API_ENDPOINT_LIVE;
this.config.dataProtectionEndpoint = Client.DATA_PROTECTION_API_ENDPOINT_LIVE;
if (liveEndpointUrlPrefix) {
this.config.endpoint =
`${Client.ENDPOINT_PROTOCOL}${liveEndpointUrlPrefix}${Client.ENDPOINT_LIVE_SUFFIX}`;

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
@@ -34,14 +36,6 @@ interface ConfigConstructor {
checkoutEndpoint?: string;
terminalApiCloudEndpoint?: string;
terminalApiLocalEndpoint?: string;
paymentEndpoint?: string;
storedValueEndpoint?: string;
terminalManagementEndpoint?: string;
managementEndpoint?: string;
balancePlatformEndpoint?: string;
legalEntityManagementEndpoint?: string;
transfersEndpoint?: string;
dataProtectionEndpoint?: string;
}
class Config {
@@ -66,15 +60,6 @@ class Config {
public terminalApiCloudEndpoint?: string;
public terminalApiLocalEndpoint?: string;
public paymentEndpoint?: string;
public storedValueEndpoint?: string;
public terminalManagementEndpoint?: string;
public managementEndpoint?: string;
public balancePlatformEndpoint?: string;
public legalEntityManagementEndpoint?: string;
public transfersEndpoint?: string;
public dataProtectionEndpoint?: string;
public constructor(options: ConfigConstructor = {}) {
if (options.username) this.username = options.username;
if (options.password) this.password = options.password;
@@ -93,14 +78,6 @@ class Config {
if (options.checkoutEndpoint) this._checkoutEndpoint = options.checkoutEndpoint;
if (options.terminalApiCloudEndpoint) this.terminalApiCloudEndpoint = options.terminalApiCloudEndpoint;
if (options.terminalApiLocalEndpoint) this.terminalApiLocalEndpoint = options.terminalApiLocalEndpoint;
if (options.paymentEndpoint) this.paymentEndpoint = options.paymentEndpoint;
if (options.storedValueEndpoint) this.storedValueEndpoint = options.storedValueEndpoint;
if (options.terminalManagementEndpoint) this.terminalManagementEndpoint = options.terminalManagementEndpoint;
if (options.managementEndpoint) this.managementEndpoint = options.managementEndpoint;
if (options.balancePlatformEndpoint) this.balancePlatformEndpoint = options.balancePlatformEndpoint;
if (options.legalEntityManagementEndpoint) this.legalEntityManagementEndpoint = options.legalEntityManagementEndpoint;
if (options.transfersEndpoint) this.transfersEndpoint = options.transfersEndpoint;
if (options.dataProtectionEndpoint) this.dataProtectionEndpoint = options.dataProtectionEndpoint;
}
public set checkoutEndpoint(checkoutEndpoint: string | undefined) {

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

View File

@@ -1,23 +1,4 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { PeerCertificate } from "tls";
import {PeerCertificate} from "tls";
export default function checkServerIdentity(host: string, cert: PeerCertificate): Error | undefined {
const { subject: { CN }} = cert;

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
@@ -20,7 +22,7 @@
import Resource from "../services/resource";
import HttpClientException from "../httpClient/httpClientException";
import ApiException from "../services/exception/apiException";
import { IRequest } from "../typings/requestOptions";
import {IRequest} from "../typings/requestOptions";
async function getJsonResponse<T>(resource: Resource, jsonRequest: T | string, requestOptions?: IRequest.Options): Promise<string>;
async function getJsonResponse<T, R>(resource: Resource, jsonRequest: T | string, requestOptions?: IRequest.Options): Promise<R>;

View File

@@ -1,23 +1,4 @@
/*
* ######
* ######
* ############ ####( ###### #####. ###### ############ ############
* ############# #####( ###### #####. ###### ############# #############
* ###### #####( ###### #####. ###### ##### ###### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ##### ######
* ###### ###### #####( ###### #####. ###### ##### ##### ######
* ############# ############# ############# ############# ##### ######
* ############ ############ ############# ############ ##### ######
* ######
* #############
* ############
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { ApplicationInfo } from "../typings/applicationInfo";
import {ApplicationInfo} from "../typings/applicationInfo";
interface AppInfo { applicationInfo?: ApplicationInfo }

View File

@@ -11,16 +11,18 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { AgentOptions } from "https";
import HttpClientException from "./httpClientException";
import ApiException from "../services/exception/apiException";
import { Config } from "../index";
import { IRequest } from "../typings/requestOptions";
import {Config} from "../index";
import {IRequest} from "../typings/requestOptions";
interface ClientInterface {
request(

View File

@@ -11,37 +11,31 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { IncomingHttpHeaders } from "http";
interface ExceptionInterface {
message: string;
statusCode?: number;
errorCode?: string;
responseHeaders?: IncomingHttpHeaders;
responseBody?: string;
}
import {IncomingHttpHeaders, IncomingMessage} from "http";
class HttpClientException implements Error {
public statusCode = 500;
public errorCode?: string;
public responseHeaders?: IncomingHttpHeaders;
public errorCode: string | undefined;
public responseHeaders: IncomingHttpHeaders | undefined;
public readonly message: string;
public readonly name: string;
public responseBody?: string;
public responseBody: IncomingMessage | undefined;
public constructor(props: ExceptionInterface) {
public constructor(message: string, statusCode?: number, errorCode?: string, responseHeaders?: IncomingHttpHeaders, responseBody?: IncomingMessage) {
this.name = "HttpClientException";
this.message = props.message;
if (props.responseHeaders) this.responseHeaders = props.responseHeaders;
if (props.responseBody) this.responseBody = props.responseBody;
if (props.errorCode) this.errorCode = props.errorCode;
if (props.statusCode) this.statusCode = props.statusCode;
this.message = message;
if(errorCode) this.errorCode = errorCode;
if(statusCode) this.statusCode = statusCode;
if(responseHeaders) this.responseHeaders = responseHeaders;
if(responseBody) this.responseBody = responseBody;
}
}

View File

@@ -11,27 +11,29 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { ClientRequest, IncomingHttpHeaders, IncomingMessage } from "http";
import { Agent, AgentOptions, request as httpsRequest } from "https";
import { HttpsProxyAgent } from "https-proxy-agent";
import {ClientRequest, IncomingMessage} from "http";
import {Agent, AgentOptions, request as httpsRequest} from "https";
import HttpsProxyAgent from "https-proxy-agent";
import * as fs from "fs";
import { URL, URLSearchParams } from "url";
import {URL} from "url";
import Client from "../client";
import Config from "../config";
import HttpClientException from "./httpClientException";
import checkServerIdentity from "../helpers/checkServerIdentity";
import { ApiError } from "../typings/apiError";
import {ApiError} from "../typings/apiError";
import ApiException from "../services/exception/apiException";
import ClientInterface from "./clientInterface";
import { ApiConstants } from "../constants/apiConstants";
import { IRequest } from "../typings/requestOptions";
import {ApiConstants} from "../constants/apiConstants";
import {IRequest} from "../typings/requestOptions";
class HttpURLConnectionClient implements ClientInterface {
private static CHARSET = "utf-8";
@@ -59,7 +61,7 @@ class HttpURLConnectionClient implements ClientInterface {
requestOptions.headers[ApiConstants.API_KEY] = apiKey;
} else {
const authString = `${config.username}:${config.password}`;
const authStringEnc = Buffer.from(authString, "utf8").toString("base64");
const authStringEnc = new Buffer(authString).toString("base64");
requestOptions.headers.Authorization = `Basic ${authStringEnc}`;
}
@@ -87,10 +89,6 @@ class HttpURLConnectionClient implements ClientInterface {
requestOptions.port = url.port;
requestOptions.path = url.pathname;
if (requestOptions.params) {
requestOptions.path += "?" + new URLSearchParams(requestOptions.params).toString();
}
if (requestOptions && requestOptions.idempotencyKey) {
requestOptions.headers[ApiConstants.IDEMPOTENCY_KEY] = requestOptions.idempotencyKey;
delete requestOptions.idempotencyKey;
@@ -104,11 +102,7 @@ class HttpURLConnectionClient implements ClientInterface {
}
requestOptions.headers["Cache-Control"] = "no-cache";
if (!requestOptions.method) {
requestOptions.method = ApiConstants.METHOD_POST;
}
requestOptions.method = ApiConstants.METHOD_POST;
requestOptions.headers[ApiConstants.ACCEPT_CHARSET] = HttpURLConnectionClient.CHARSET;
requestOptions.headers[ApiConstants.USER_AGENT] = `${applicationName} ${Client.LIB_NAME}/${Client.LIB_VERSION}`;
@@ -124,49 +118,33 @@ class HttpURLConnectionClient implements ClientInterface {
connectionRequest.flushHeaders();
connectionRequest.on("response", (res: IncomingMessage): void => {
const response: { headers: IncomingHttpHeaders; body: string; statusCode: number | undefined } = {
statusCode: res.statusCode,
headers: res.headers,
body: ""
};
let resData = "";
const getException = (): HttpClientException => new HttpClientException(
`HTTP Exception: ${res.statusCode}. ${res.statusMessage}`,
res.statusCode,
undefined,
res.headers,
res,
);
let exception: HttpClientException | Error = getException();
const getException = (responseBody: string): HttpClientException => new HttpClientException({
message: `HTTP Exception: ${response.statusCode}. ${res.statusMessage}`,
statusCode: response.statusCode,
errorCode: undefined,
responseHeaders: response.headers,
responseBody,
});
let exception: HttpClientException | Error = getException(response.body.toString());
res.on("data", (chunk: string): void => {
response.body += chunk;
});
res.on("end", (): void => {
if (!res.complete) {
reject(new Error("The connection was terminated while the message was still being sent"));
}
if (res.statusCode && (res.statusCode < 200 || res.statusCode >= 300)) {
res.on("data", (data): void => {
if (res.statusCode && res.statusCode !== 200) {
try {
const formattedData: ApiError | {[key: string]: never} = JSON.parse(response.body);
const formattedData: ApiError = JSON.parse(data.toString() as string);
const isApiError = "status" in formattedData;
const isRequestError = "errors" in formattedData;
if (isApiError) {
exception = new HttpClientException({
message: `HTTP Exception: ${formattedData.status}. ${res.statusMessage}: ${formattedData.message}`,
statusCode: formattedData.status,
errorCode: formattedData.errorCode,
responseHeaders: res.headers,
responseBody: response.body,
});
exception = new HttpClientException(
`HTTP Exception: ${formattedData.status}. ${res.statusMessage}: ${formattedData.message}`,
formattedData.status,
formattedData.errorCode,
res.headers,
res,
);
} else if (isRequestError) {
exception = new Error(response.body);
} else {
exception = getException(response.body);
exception = new Error(data);
}
} catch (e) {
reject(exception);
@@ -175,7 +153,14 @@ class HttpURLConnectionClient implements ClientInterface {
}
}
resolve(response.body as string);
resData += data;
});
res.on("end", (): void => {
if (!res.complete) {
reject(new Error("The connection was terminated while the message was still being sent"));
}
resolve(resData);
});
res.on("error", reject);
@@ -200,8 +185,7 @@ class HttpURLConnectionClient implements ClientInterface {
};
} catch (e) {
const message = e instanceof Error ? e.message: "undefined";
return Promise.reject(new HttpClientException({ message: `Error loading certificate from path: ${message}` }));
return Promise.reject(new HttpClientException(`Error loading certificate from path: ${e.message}`));
}
}

20
src/index.d.ts vendored Normal file
View File

@@ -0,0 +1,20 @@
/// <reference path="typings/amount.ts" />
/// <reference path="typings/apiError.ts" />
/// <reference path="typings/applicationInfo.ts" />
/// <reference path="typings/binLookup.ts" />
/// <reference path="typings/checkout.ts" />
/// <reference path="typings/checkoutUtility.ts" />
/// <reference path="typings/enums/environment.ts" />
/// <reference path="typings/enums/vatCategory.ts" />
/// <reference path="typings/marketPayAccount.ts" />
/// <reference path="typings/marketPayFund.ts" />
/// <reference path="typings/marketPayHostedOnboardingPage.ts" />
/// <reference path="typings/marketPayNotificationConfiguration.ts" />
/// <reference path="typings/marketPayNotifications.ts" />
/// <reference path="typings/nexo.ts" />
/// <reference path="typings/notification.ts" />
/// <reference path="typings/payments.ts" />
/// <reference path="typings/payouts.ts" />
/// <reference path="typings/recurring.ts" />
/// <reference path="typings/requestOptions.ts" />
/// <reference path="typings/terminal.ts" />

View File

@@ -11,18 +11,38 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2021 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import "./typings";
/* eslint-disable @typescript-eslint/triple-slash-reference */
/// <reference path="typings/amount.ts" />
/// <reference path="typings/apiError.ts" />
/// <reference path="typings/applicationInfo.ts" />
/// <reference path="typings/binLookup.ts" />
/// <reference path="typings/checkout.ts" />
/// <reference path="typings/checkoutUtility.ts" />
/// <reference path="typings/enums/environment.ts" />
/// <reference path="typings/enums/vatCategory.ts" />
/// <reference path="typings/marketPayAccount.ts" />
/// <reference path="typings/marketPayFund.ts" />
/// <reference path="typings/marketPayHostedOnboardingPage.ts" />
/// <reference path="typings/marketPayNotificationConfiguration.ts" />
/// <reference path="typings/marketPayNotifications.ts" />
/// <reference path="typings/nexo.ts" />
/// <reference path="typings/notification.ts" />
/// <reference path="typings/payments.ts" />
/// <reference path="typings/payouts.ts" />
/// <reference path="typings/recurring.ts" />
/// <reference path="typings/requestOptions.ts" />
/// <reference path="typings/terminal.ts" />
export { default as Client } from "./client";
export { default as Config } from "./config";
export * from "./services/";
export { hmacValidator } from "./utils";
export { default as HttpURLConnectionClient } from "./httpClient/httpURLConnectionClient";
export * as Types from "./typings";

View File

@@ -11,21 +11,18 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import {
Notification,
NotificationItem,
NotificationRequestItem,
ObjectSerializer
} from "../typings/notification/models";
import {Convert, Notification, NotificationItem, NotificationRequestItem} from "../typings/notification";
class NotificationRequest {
public constructor(json: Notification) {
const notification: Notification = ObjectSerializer.deserialize(json, "Notification");
const notification = Convert.toNotification(JSON.stringify(json));
this.notificationItemContainers = notification.notificationItems;
this.live = notification.live;
}

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

View File

@@ -11,24 +11,26 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2021 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { Cipher, createCipheriv, createDecipheriv, createHmac, randomBytes, timingSafeEqual } from "crypto";
import {Cipher, createCipheriv, createDecipheriv, createHmac, randomBytes} from "crypto";
import NexoCryptoException from "../services/exception/nexoCryptoException";
import {
MessageHeader,
NexoDerivedKey,
SaleToPOISecuredMessage,
SaleToPoiSecuredMessage,
SecurityKey,
SecurityTrailer,
} from "../typings/terminal/models";
} from "../typings/terminal";
import InvalidSecurityKeyException from "./exception/invalidSecurityKeyException";
import NexoDerivedKeyGenerator from "./nexoDerivedKeyGenerator";
import { NexoEnum } from "../constants/nexoConstants";
import {NexoEnum} from "../constants/nexoConstants";
enum Modes {
ENCRYPT,
@@ -40,49 +42,49 @@ class NexoCrypto {
messageHeader: MessageHeader,
saleToPoiMessageJson: string,
securityKey: SecurityKey,
): SaleToPOISecuredMessage {
const derivedKey: NexoDerivedKey = NexoDerivedKeyGenerator.deriveKeyMaterial(securityKey.Passphrase);
const saleToPoiMessageByteArray = Buffer.from(saleToPoiMessageJson, "utf-8");
): SaleToPoiSecuredMessage {
const derivedKey: NexoDerivedKey = NexoDerivedKeyGenerator.deriveKeyMaterial(securityKey.passphrase);
const saleToPoiMessageByteArray = Buffer.from(saleToPoiMessageJson, "ascii");
const ivNonce = NexoCrypto.generateRandomIvNonce();
const encryptedSaleToPoiMessage = NexoCrypto.crypt(saleToPoiMessageByteArray, derivedKey, ivNonce, Modes.ENCRYPT);
const encryptedSaleToPoiMessageHmac = NexoCrypto.hmac(saleToPoiMessageByteArray, derivedKey);
const securityTrailer: SecurityTrailer = {
AdyenCryptoVersion: securityKey.AdyenCryptoVersion,
Hmac: encryptedSaleToPoiMessageHmac.toString("base64"),
KeyIdentifier: securityKey.KeyIdentifier,
KeyVersion: securityKey.KeyVersion,
Nonce: ivNonce.toString("base64"),
adyenCryptoVersion: securityKey.adyenCryptoVersion,
hmac: encryptedSaleToPoiMessageHmac.toString("base64"),
keyIdentifier: securityKey.keyIdentifier,
keyVersion: securityKey.keyVersion,
nonce: ivNonce.toString("base64"),
};
return {
MessageHeader: messageHeader,
NexoBlob: encryptedSaleToPoiMessage.toString("base64"),
SecurityTrailer: securityTrailer,
messageHeader,
nexoBlob: encryptedSaleToPoiMessage.toString("base64"),
securityTrailer: securityTrailer,
};
}
public decrypt(saleToPoiSecureMessage: SaleToPOISecuredMessage, securityKey: SecurityKey): string {
public decrypt(saleToPoiSecureMessage: SaleToPoiSecuredMessage, securityKey: SecurityKey): string {
NexoCrypto.validateSecurityKey(securityKey);
const encryptedSaleToPoiMessageByteArray = Buffer.from(saleToPoiSecureMessage.NexoBlob, "base64");
const derivedKey = NexoDerivedKeyGenerator.deriveKeyMaterial(securityKey.Passphrase);
const ivNonce = Buffer.from(saleToPoiSecureMessage.SecurityTrailer.Nonce, "base64");
const encryptedSaleToPoiMessageByteArray = Buffer.from(saleToPoiSecureMessage.nexoBlob, "base64");
const derivedKey = NexoDerivedKeyGenerator.deriveKeyMaterial(securityKey.passphrase);
const ivNonce = Buffer.from(saleToPoiSecureMessage.securityTrailer.nonce, "base64");
const decryptedSaleToPoiMessageByteArray =
NexoCrypto.crypt(encryptedSaleToPoiMessageByteArray, derivedKey, ivNonce, Modes.DECRYPT);
const receivedHmac = Buffer.from(saleToPoiSecureMessage.SecurityTrailer.Hmac, "base64");
const receivedHmac = Buffer.from(saleToPoiSecureMessage.securityTrailer.hmac, "base64");
this.validateHmac(receivedHmac, decryptedSaleToPoiMessageByteArray, derivedKey);
return decryptedSaleToPoiMessageByteArray.toString("utf-8");
return decryptedSaleToPoiMessageByteArray.toString("ascii");
}
private static validateSecurityKey(securityKey: SecurityKey): void {
const isValid = securityKey
&& securityKey.Passphrase
&& securityKey.KeyIdentifier
&& !isNaN(securityKey.KeyVersion)
&& !isNaN(securityKey.AdyenCryptoVersion);
&& securityKey.passphrase
&& securityKey.keyIdentifier
&& securityKey.keyVersion
&& securityKey.adyenCryptoVersion;
if (!isValid) {
throw new InvalidSecurityKeyException("Invalid Security Key");
}
@@ -115,7 +117,9 @@ class NexoCrypto {
private validateHmac(receivedHmac: Buffer, decryptedMessage: Buffer, derivedKey: NexoDerivedKey): void {
const hmac = NexoCrypto.hmac(decryptedMessage, derivedKey);
if (!timingSafeEqual(hmac, receivedHmac)) {
const isValid = hmac.every((item, index): boolean => item === receivedHmac[index]);
if (!isValid) {
throw new NexoCryptoException("Hmac validation failed");
}
}

View File

@@ -11,15 +11,17 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/
import { pbkdf2Sync } from "crypto";
import { NexoDerivedKey } from "../typings/terminal/models";
import { NexoEnum } from "../constants/nexoConstants";
import {pbkdf2Sync} from "crypto";
import { NexoDerivedKey } from "../typings/terminal";
import {NexoEnum} from "../constants/nexoConstants";
class NexoDerivedKeyGenerator {
public static deriveKeyMaterial(passphrase: string): NexoDerivedKey {

View File

@@ -11,8 +11,10 @@
* ######
* #############
* ############
*
* Adyen NodeJS API Library
* Copyright (c) 2020 Adyen B.V.
*
* Copyright (c) 2019 Adyen B.V.
* This file is open source and available under the MIT license.
* See the LICENSE file for more info.
*/

View File

@@ -1,52 +0,0 @@
import getJsonResponse from "../../helpers/getJsonResponse";
import Service from "../../service";
import { AccountHolder, AccountHolderInfo, ObjectSerializer, PaginatedBalanceAccountsResponse } from "../../typings/balancePlatform/models";
import { IRequest } from "../../typings/requestOptions";
import BalancePlatformResource from "../resource/balancePlaftformResource";
// @TODO PW-7013: make this change at the spec level?
export type AccountHolderUpdate = Omit<AccountHolder, "id">;
class AccountHolders extends Service {
public async create(request: AccountHolderInfo): Promise<AccountHolder> {
const resource = new BalancePlatformResource(this, "/accountHolders");
const response = await getJsonResponse<AccountHolderInfo, AccountHolder>(
resource,
request,
{ method: "POST" }
);
return ObjectSerializer.deserialize(response, "AccountHolder");
}
public async retrieve(id: string): Promise<AccountHolder> {
const resource = new BalancePlatformResource(this, `/accountHolders/${id}`);
const response = await getJsonResponse<string, AccountHolder>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "AccountHolder");
}
public async update(id: string, request: AccountHolderUpdate): Promise<AccountHolder> {
const resource = new BalancePlatformResource(this, `/accountHolders/${id}`);
const response = await getJsonResponse<AccountHolderUpdate, AccountHolder>(
resource,
request,
{ method: "PATCH" }
);
return ObjectSerializer.deserialize(response, "AccountHolder");
}
public async listBalanceAccounts(id: string, requestOptions?: IRequest.Options): Promise<PaginatedBalanceAccountsResponse> {
const resource = new BalancePlatformResource(this, `/accountHolders/${id}/balanceAccounts`);
const response = await getJsonResponse<string, PaginatedBalanceAccountsResponse>(
resource,
"",
{ ...requestOptions, method: "GET" }
);
return ObjectSerializer.deserialize(response, "PaginatedBalanceAccountsResponse");
}
}
export default AccountHolders;

View File

@@ -1,103 +0,0 @@
import getJsonResponse from "../../helpers/getJsonResponse";
import Service from "../../service";
import { BalanceAccount, BalanceAccountInfo, BalanceAccountUpdateRequest, BalanceSweepConfigurationsResponse, ObjectSerializer, PaginatedPaymentInstrumentsResponse, SweepConfigurationV2 } from "../../typings/balancePlatform/models";
import { IRequest } from "../../typings/requestOptions";
import BalancePlatformResource from "../resource/balancePlaftformResource";
// @TODO PW-7013: make this change at the spec level?
export type SweepConfigurationV2Create = Omit<SweepConfigurationV2, "id">;
export type SweepConfigurationV2Update = Partial<SweepConfigurationV2>;
class BalanceAccounts extends Service {
public async create(request: BalanceAccountInfo): Promise<BalanceAccount> {
const resource = new BalancePlatformResource(this, "/balanceAccounts");
const response = await getJsonResponse<BalanceAccountInfo, BalanceAccount>(
resource,
request,
{ method: "POST" }
);
return ObjectSerializer.deserialize(response, "BalanceAccount");
}
public async listSweeps(balanceAccountId: string, requestOptions?: IRequest.Options): Promise<BalanceSweepConfigurationsResponse> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${balanceAccountId}/sweeps`);
const response = await getJsonResponse<string, BalanceSweepConfigurationsResponse>(
resource,
"",
{ ...requestOptions, method: "GET" }
);
return ObjectSerializer.deserialize(response, "BalanceSweepConfigurationsResponse");
}
public async createSweep(balanceAccountId: string, request: SweepConfigurationV2Create): Promise<SweepConfigurationV2> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${balanceAccountId}/sweeps`);
const response = await getJsonResponse<SweepConfigurationV2Create, SweepConfigurationV2>(
resource,
request,
{ method: "POST" }
);
return ObjectSerializer.deserialize(response, "SweepConfigurationV2");
}
public async deleteSweep(balanceAccountId: string, sweepId: string): Promise<void> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`);
await getJsonResponse<string, string>(
resource,
"",
{ method: "DELETE" }
);
}
public async retrieveSweep(balanceAccountId: string, sweepId: string): Promise<SweepConfigurationV2> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`);
const response = await getJsonResponse<string, SweepConfigurationV2>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "SweepConfigurationV2");
}
public async updateSweep(balanceAccountId: string, sweepId: string, request: SweepConfigurationV2Update): Promise<SweepConfigurationV2> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${balanceAccountId}/sweeps/${sweepId}`);
const response = await getJsonResponse<SweepConfigurationV2Update, SweepConfigurationV2>(
resource,
request,
{ method: "PATCH" }
);
return ObjectSerializer.deserialize(response, "SweepConfigurationV2");
}
public async retrieve(id: string): Promise<BalanceAccount> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${id}`);
const response = await getJsonResponse<string, BalanceAccount>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "BalanceAccount");
}
public async update(id: string, request: BalanceAccountUpdateRequest): Promise<BalanceAccount> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${id}`);
const response = await getJsonResponse<BalanceAccountUpdateRequest, BalanceAccount>(
resource,
request,
{ method: "PATCH" }
);
return ObjectSerializer.deserialize(response, "BalanceAccount");
}
public async listPaymentInstruments(id: string, requestOptions?: IRequest.Options): Promise<PaginatedPaymentInstrumentsResponse> {
const resource = new BalancePlatformResource(this, `/balanceAccounts/${id}/paymentInstruments`);
const response = await getJsonResponse<string, PaginatedPaymentInstrumentsResponse>(
resource,
"",
{ ...requestOptions, method: "GET" }
);
return ObjectSerializer.deserialize(response, "PaginatedPaymentInstrumentsResponse");
}
}
export default BalanceAccounts;

View File

@@ -1,29 +0,0 @@
import getJsonResponse from "../../helpers/getJsonResponse";
import Service from "../../service";
import { BalancePlatform, ObjectSerializer, PaginatedAccountHoldersResponse } from "../../typings/balancePlatform/models";
import { IRequest } from "../../typings/requestOptions";
import BalancePlatformResource from "../resource/balancePlaftformResource";
class General extends Service {
public async retrieve(id: string): Promise<BalancePlatform> {
const resource = new BalancePlatformResource(this, `/balancePlatforms/${id}`);
const response = await getJsonResponse<string, BalancePlatform>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "BalancePlatform");
}
public async listAccountHolders(id: string, requestOptions?: IRequest.Options): Promise<PaginatedAccountHoldersResponse> {
const resource = new BalancePlatformResource(this, `/balancePlatforms/${id}/accountHolders`);
const response = await getJsonResponse<string, PaginatedAccountHoldersResponse>(
resource,
"",
{ ...requestOptions, method: "GET" }
);
return ObjectSerializer.deserialize(response, "PaginatedAccountHoldersResponse");
}
}
export default General;

View File

@@ -1,39 +0,0 @@
import getJsonResponse from "../../helpers/getJsonResponse";
import Service from "../../service";
import { ObjectSerializer, PaymentInstrumentGroup, PaymentInstrumentGroupInfo, TransactionRulesResponse } from "../../typings/balancePlatform/models";
import BalancePlatformResource from "../resource/balancePlaftformResource";
class PaymentInstrumentGroups extends Service {
public async create(request: PaymentInstrumentGroupInfo): Promise<PaymentInstrumentGroup> {
const resource = new BalancePlatformResource(this, "/paymentInstrumentGroups");
const response = await getJsonResponse<PaymentInstrumentGroupInfo, PaymentInstrumentGroup>(
resource,
request,
{ method: "POST" }
);
return ObjectSerializer.deserialize(response, "PaymentInstrumentGroup");
}
public async retrieve(id: string): Promise<PaymentInstrumentGroup> {
const resource = new BalancePlatformResource(this, `/paymentInstrumentGroups/${id}`);
const response = await getJsonResponse<string, PaymentInstrumentGroup>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "PaymentInstrumentGroup");
}
public async listTransactionRules(id: string): Promise<TransactionRulesResponse> {
const resource = new BalancePlatformResource(this, `/paymentInstrumentGroups/${id}/transactionRules`);
const response = await getJsonResponse<string, TransactionRulesResponse>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "TransactionRulesResponse");
}
}
export default PaymentInstrumentGroups;

View File

@@ -1,48 +0,0 @@
import getJsonResponse from "../../helpers/getJsonResponse";
import Service from "../../service";
import { ObjectSerializer, PaymentInstrument, PaymentInstrumentInfo, PaymentInstrumentUpdateRequest, TransactionRulesResponse } from "../../typings/balancePlatform/models";
import BalancePlatformResource from "../resource/balancePlaftformResource";
class PaymentInstruments extends Service {
public async create(request: PaymentInstrumentInfo): Promise<PaymentInstrument> {
const resource = new BalancePlatformResource(this, "/paymentInstruments");
const response = await getJsonResponse<PaymentInstrumentInfo, PaymentInstrument>(
resource,
request,
{ method: "POST" }
);
return ObjectSerializer.deserialize(response, "PaymentInstrument");
}
public async retrieve(id: string): Promise<PaymentInstrument> {
const resource = new BalancePlatformResource(this, `/paymentInstruments/${id}`);
const response = await getJsonResponse<string, PaymentInstrument>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "PaymentInstrument");
}
public async update(id: string, request: PaymentInstrumentUpdateRequest): Promise<PaymentInstrument> {
const resource = new BalancePlatformResource(this, `/paymentInstruments/${id}`);
const response = await getJsonResponse<PaymentInstrumentUpdateRequest, PaymentInstrument>(
resource,
request,
{ method: "PATCH" }
);
return ObjectSerializer.deserialize(response, "PaymentInstrument");
}
public async listTransactionRules(id: string): Promise<TransactionRulesResponse> {
const resource = new BalancePlatformResource(this, `/paymentInstruments/${id}/transactionRules`);
const response = await getJsonResponse<string, TransactionRulesResponse>(
resource,
"",
{ method: "GET" }
);
return ObjectSerializer.deserialize(response, "TransactionRulesResponse");
}
}
export default PaymentInstruments;

Some files were not shown because too many files have changed in this diff Show More