├── .gitattributes ├── .npmignore ├── .node-version ├── .npmrc ├── .yarnrc ├── pure.js ├── tests ├── versions │ ├── .gitignore │ ├── .eslintrc.yml │ ├── tsconfig.json │ ├── src │ │ └── index.ts │ └── scripts │ │ └── test.sh └── types │ ├── tsconfig.json │ ├── fixtures │ ├── createTerminalExtraProperty.ts │ └── discoverReadersExtraProperty.ts │ ├── errors.test.ts │ └── index.ts ├── .babelrc ├── .gitignore ├── .prettierignore ├── .eslintignore ├── .prettierrc.yml ├── types ├── .eslintrc.yml ├── index.d.ts ├── terminal.d.ts └── proto.d.ts ├── src ├── pure.ts ├── index.ts ├── pure.test.ts ├── shared.ts └── index.test.ts ├── .circleci └── config.yml ├── .github ├── pull_request_template.md └── ISSUE_TEMPLATE.md ├── jest.config.js ├── pure.d.ts ├── tsconfig.json ├── rollup.config.js ├── .eslintrc.yaml ├── LICENSE ├── package.json ├── scripts └── publish └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | examples -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 18.14.0 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.yarnrc: -------------------------------------------------------------------------------- 1 | registry "https://registry.npmjs.org/" 2 | 3 | -------------------------------------------------------------------------------- /pure.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/pure.js'); 2 | -------------------------------------------------------------------------------- /tests/versions/.gitignore: -------------------------------------------------------------------------------- 1 | package.json 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .cache 3 | dist 4 | node_modules 5 | *.log 6 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | package.json 4 | types/proto.d.ts 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | examples 4 | tests/types 5 | types/proto.d.ts 6 | -------------------------------------------------------------------------------- /tests/versions/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | '@typescript-eslint/no-non-null-assertion': 0 3 | -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | singleQuote: true 2 | trailingComma: es5 3 | bracketSpacing: false 4 | arrowParens: always 5 | proseWrap: always 6 | -------------------------------------------------------------------------------- /types/.eslintrc.yml: -------------------------------------------------------------------------------- 1 | rules: 2 | '@typescript-eslint/triple-slash-reference': 0 3 | '@typescript-eslint/adjacent-overload-signatures': 0 4 | -------------------------------------------------------------------------------- /src/pure.ts: -------------------------------------------------------------------------------- 1 | import {StripeTerminal} from '../types/index'; 2 | import {loadScript} from './shared'; 3 | 4 | export const loadStripeTerminal = (): Promise => 5 | loadScript(); 6 | -------------------------------------------------------------------------------- /tests/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "esnext", 5 | "moduleResolution": "node", 6 | "noEmit": true, 7 | "strict": true 8 | }, 9 | "include": ["./index.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /tests/versions/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "esnext", 4 | "module": "esnext", 5 | "noEmit": true, 6 | "strict": true, 7 | "moduleResolution": "node", 8 | "types": ["../.."], 9 | "skipLibCheck": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # This config is equivalent to both the '.circleci/extended/orb-free.yml' and the base '.circleci/config.yml' 2 | version: 2.1 3 | 4 | orbs: 5 | node: circleci/node@5.0.2 6 | workflows: 7 | test_my_app: 8 | jobs: 9 | - node/test: 10 | run-command: ci 11 | pkg-manager: yarn 12 | version: lts 13 | -------------------------------------------------------------------------------- /tests/versions/src/index.ts: -------------------------------------------------------------------------------- 1 | import {loadStripeTerminal} from '../../../types/index'; 2 | 3 | const main = async (): Promise => { 4 | // setup Terminal 5 | const StripeTerminal = (await loadStripeTerminal())!; 6 | 7 | const terminal = StripeTerminal.create({ 8 | onFetchConnectionToken: async () => 'test_token', 9 | }); 10 | 11 | terminal.discoverReaders(); 12 | }; 13 | 14 | main(); 15 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ### Summary & motivation 2 | 3 | 4 | 5 | ### Testing & documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | roots: ['/src'], 3 | testMatch: [ 4 | '**/__tests__/**/*.+(ts|tsx|js)', 5 | '**/?(*.)+(spec|test).+(ts|tsx|js)', 6 | ], 7 | transform: { 8 | '^.+\\.(ts|tsx)$': 'ts-jest', 9 | }, 10 | testEnvironment: 'jsdom', 11 | globals: { 12 | // Suppress noise about enabling `esModuleInterop` 13 | 'ts-jest': {diagnostics: {ignoreCodes: [151001]}}, 14 | _VERSION: true, 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /tests/types/fixtures/createTerminalExtraProperty.ts: -------------------------------------------------------------------------------- 1 | import {loadStripeTerminal} from '../../../types/index'; 2 | 3 | const main = async (): Promise => { 4 | // setup Terminal 5 | const StripeTerminal = (await loadStripeTerminal())!; 6 | 7 | const terminal = StripeTerminal.create({ 8 | onFetchConnectionToken: async () => 'test_token', 9 | extra_property: 'foo', 10 | }); 11 | 12 | terminal.discoverReaders(); 13 | }; 14 | 15 | main(); 16 | -------------------------------------------------------------------------------- /tests/types/fixtures/discoverReadersExtraProperty.ts: -------------------------------------------------------------------------------- 1 | import {loadStripeTerminal} from '../../../types/index'; 2 | 3 | const main = async (): Promise => { 4 | // setup Terminal 5 | const StripeTerminal = (await loadStripeTerminal())!; 6 | 7 | const terminal = StripeTerminal.create({ 8 | onFetchConnectionToken: async () => 'test_token', 9 | }); 10 | 11 | terminal.discoverReaders({ 12 | extraneous: 'property', 13 | }); 14 | }; 15 | 16 | main(); 17 | -------------------------------------------------------------------------------- /pure.d.ts: -------------------------------------------------------------------------------- 1 | import {loadStripeTerminal as IloadStripeTerminal} from './src/pure'; 2 | import { 3 | Terminal, 4 | PaymentStatus, 5 | ConnectionStatus, 6 | OutputLogLevel, 7 | TerminalProps, 8 | } from './types/terminal'; 9 | 10 | export * from './types/terminal'; 11 | 12 | export interface StripeTerminal { 13 | create(props: TerminalProps): Terminal; 14 | PaymentStatus: PaymentStatus; 15 | ConnectionStatus: ConnectionStatus; 16 | OutputLogLevel: OutputLogLevel; 17 | } 18 | 19 | export const loadStripeTerminal: typeof IloadStripeTerminal; 20 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import {StripeTerminal} from '../types/index'; 2 | import {loadScript} from './shared'; 3 | 4 | // Execute our own script injection after a tick to give users time to do their 5 | // own script injection. 6 | const stripePromise = Promise.resolve().then(loadScript); 7 | 8 | let loadCalled = false; 9 | 10 | stripePromise.catch((err) => { 11 | if (!loadCalled) { 12 | console.warn(err); 13 | } 14 | }); 15 | 16 | export const loadStripeTerminal = (): Promise => { 17 | loadCalled = true; 18 | 19 | return stripePromise; 20 | }; 21 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Let Babel deal with transpiling new language features 4 | "target": "esnext", 5 | 6 | // These are overridden by the Rollup plugin, but are left here in case you 7 | // run `tsc` directly for typechecking or debugging purposes 8 | "outDir": "./dist", 9 | "rootDir": "./src", 10 | 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "noEmit": true, 14 | "allowJs": false, 15 | "declaration": false, 16 | "removeComments": false, 17 | "strict": true, 18 | "forceConsistentCasingInFileNames": true 19 | }, 20 | "include": ["src"] 21 | } 22 | -------------------------------------------------------------------------------- /tests/versions/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | 5 | # Ensure working directory is test directory 6 | cd "$(dirname "$0")/.." 7 | 8 | [ -f package.json ] && rm package.json 9 | yarn init -sy 10 | 11 | versions=( 12 | "next" 13 | "beta" 14 | "latest" 15 | "4.3.5" 16 | "4.2.4" 17 | "4.1.5" 18 | ) 19 | 20 | for version in ${versions[@]}; do 21 | echo "--- Testing with TypeScript version $version" 22 | yarn add -s --no-progress typescript@$version 23 | 24 | if [ "$version" == "next" ]; then 25 | # Add ignoreDeprecations option for 'next' version 26 | yarn run tsc --ignoreDeprecations 6.0 27 | else 28 | yarn run tsc 29 | fi 30 | done 31 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import { 3 | Terminal, 4 | TerminalProps, 5 | PaymentStatus, 6 | ConnectionStatus, 7 | OutputLogLevel, 8 | } from './terminal'; 9 | 10 | export * from './terminal'; 11 | 12 | export interface StripeTerminal { 13 | create(props: TerminalProps): Terminal; 14 | PaymentStatus: PaymentStatus; 15 | ConnectionStatus: ConnectionStatus; 16 | OutputLogLevel: OutputLogLevel; 17 | } 18 | 19 | export const loadStripeTerminal: () => Promise; 20 | 21 | declare global { 22 | interface Window { 23 | // Terminal's sdk.js must be loaded directly from https://js.stripe.com/v3, which 24 | // places a `StripeTerminal` object on the window 25 | StripeTerminal?: StripeTerminal; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import babel from 'rollup-plugin-babel'; 2 | import ts from 'rollup-plugin-typescript2'; 3 | import replace from '@rollup/plugin-replace'; 4 | 5 | import pkg from './package.json'; 6 | 7 | const PLUGINS = [ 8 | ts({ 9 | tsconfigOverride: {exclude: ['**/*.test.ts']}, 10 | }), 11 | babel({ 12 | extensions: ['.ts', '.js', '.tsx', '.jsx'], 13 | }), 14 | replace({ 15 | _VERSION: JSON.stringify(pkg.version), 16 | }), 17 | ]; 18 | 19 | export default [ 20 | { 21 | input: 'src/index.ts', 22 | output: [ 23 | {file: pkg.main, format: 'cjs'}, 24 | {file: pkg.module, format: 'es'}, 25 | ], 26 | plugins: PLUGINS, 27 | }, 28 | { 29 | input: 'src/pure.ts', 30 | output: [{file: 'dist/pure.js', format: 'cjs'}], 31 | plugins: PLUGINS, 32 | }, 33 | ]; 34 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ### Summary 12 | 13 | 14 | 15 | ### Other information 16 | 17 | 18 | -------------------------------------------------------------------------------- /.eslintrc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | root: true 3 | extends: 4 | - eslint:recommended 5 | - plugin:@typescript-eslint/eslint-recommended 6 | - plugin:@typescript-eslint/recommended 7 | - prettier 8 | parser: '@typescript-eslint/parser' 9 | plugins: 10 | - jest 11 | - prettier 12 | - '@typescript-eslint' 13 | env: 14 | jest/globals: true 15 | browser: true 16 | rules: 17 | no-console: 0 18 | func-style: 2 19 | consistent-return: 2 20 | prefer-arrow-callback: 21 | - 2 22 | - allowNamedFunctions: false 23 | allowUnboundThis: false 24 | no-unused-vars: 25 | - 2 26 | - ignoreRestSiblings: true 27 | jest/no-disabled-tests: 2 28 | jest/no-focused-tests: 2 29 | '@typescript-eslint/camelcase': 0 30 | '@typescript-eslint/no-explicit-any': 0 31 | '@typescript-eslint/no-empty-interface': 0 32 | '@typescript-eslint/triple-slash-reference': 0 33 | -------------------------------------------------------------------------------- /src/pure.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | 3 | const SCRIPT_SELECTOR = 4 | 'script[src="https://js.stripe.com/terminal/v1"], script[src="https://js.stripe.com/terminal/v1/"]'; 5 | 6 | describe('pure module', () => { 7 | afterEach(() => { 8 | const script = document.querySelector(SCRIPT_SELECTOR); 9 | if (script && script.parentElement) { 10 | script.parentElement.removeChild(script); 11 | } 12 | 13 | delete window.StripeTerminal; 14 | jest.resetModules(); 15 | }); 16 | 17 | test('does not inject the script if loadStripeTerminal is not called', async () => { 18 | require('./pure'); 19 | 20 | expect(document.querySelector(SCRIPT_SELECTOR)).toBe(null); 21 | }); 22 | 23 | test('it injects the script if loadStripeTerminal is called', async () => { 24 | const {loadStripeTerminal} = require('./pure'); 25 | loadStripeTerminal(); 26 | 27 | expect(document.querySelector(SCRIPT_SELECTOR)).not.toBe(null); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /tests/types/errors.test.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path'; 2 | import {readFileSync} from 'fs'; 3 | 4 | import * as ts from 'typescript'; 5 | 6 | const parsedCommandLine = ts.getParsedCommandLineOfConfigFile( 7 | path.resolve(__dirname, 'tsconfig.json'), 8 | {}, 9 | { 10 | ...ts.sys, 11 | getCurrentDirectory: () => __dirname, 12 | onUnRecoverableConfigFileDiagnostic: () => {}, 13 | } 14 | )!; 15 | 16 | const getError = function(fileName: string) { 17 | const program = ts.createProgram([fileName], parsedCommandLine.options); 18 | const diagnostics = ts.getPreEmitDiagnostics(program); 19 | 20 | return ts.flattenDiagnosticMessageText(diagnostics[0].messageText, '\n'); 21 | }; 22 | 23 | describe('Typescript errors', () => { 24 | test.each([['createTerminalExtraProperty', 'extra_property']])( 25 | '%s', 26 | (fileName, expectedError) => { 27 | expect( 28 | getError(path.resolve(__dirname, `./fixtures/${fileName}.ts`)) 29 | ).toMatch(expectedError); 30 | } 31 | ); 32 | }); 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Stripe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/types/index.ts: -------------------------------------------------------------------------------- 1 | import {assert, Has} from 'conditional-type-checks'; 2 | 3 | /* 4 | * This code will not run, but will be typechecked as a test. 5 | */ 6 | 7 | import { 8 | loadStripeTerminal, 9 | StripeTerminal as IStripeTerminal, 10 | DiscoverResult, 11 | Reader, 12 | IErrorResponse, 13 | ErrorResponse, 14 | SdkManagedPaymentIntent, 15 | } from '../../types/index'; 16 | 17 | declare const StripeTerminal: IStripeTerminal; 18 | 19 | const main = async () => { 20 | const stripePromise: Promise = loadStripeTerminal(); 21 | 22 | type SrcModule = typeof import('../../src/index'); 23 | 24 | const terminal = StripeTerminal.create({ 25 | onFetchConnectionToken: async () => 'test_token', 26 | }); 27 | 28 | terminal.overrideBaseURL('http://foo'); 29 | 30 | const discoverResult: 31 | | DiscoverResult 32 | | ErrorResponse = await terminal.discoverReaders({ 33 | device_type: 'foo', 34 | }); 35 | 36 | const reader: {reader: Reader} | ErrorResponse = await terminal.connectReader( 37 | { 38 | id: 'id', 39 | object: 'terminal.reader', 40 | device_type: 'verifone_P400', 41 | ip_address: 'address', 42 | serial_number: 'serial', 43 | livemode: false, 44 | device_sw_version: '0.0.0', 45 | label: 'foo', 46 | location: null, 47 | metadata: {}, 48 | status: 'online', 49 | } 50 | ); 51 | 52 | const connReader: Reader = terminal.getConnectedReader(); 53 | 54 | terminal.disconnectReader(); 55 | 56 | const clearResp: {} | ErrorResponse = terminal.clearCachedCredentials(); 57 | 58 | const clearDispResp: {} | ErrorResponse = terminal.clearReaderDisplay(); 59 | 60 | const setDispResp: {} | ErrorResponse = terminal.setReaderDisplay({ 61 | type: 'type', 62 | }); 63 | 64 | const payIntent: 65 | | {paymentIntent: SdkManagedPaymentIntent} 66 | | ErrorResponse = await terminal.collectPaymentMethod('pay_intent'); 67 | }; 68 | 69 | main(); 70 | -------------------------------------------------------------------------------- /src/shared.ts: -------------------------------------------------------------------------------- 1 | import {StripeTerminal} from '../types/index'; 2 | 3 | // `_VERSION` will be rewritten by `@rollup/plugin-replace` as a string literal 4 | // containing the package.json version 5 | // declare const _VERSION: string; 6 | 7 | const V1_URL = 'https://js.stripe.com/terminal/v1'; 8 | 9 | const injectScript = (): HTMLScriptElement => { 10 | const script = document.createElement('script'); 11 | script.src = V1_URL; 12 | 13 | const headOrBody = document.head || document.body; 14 | 15 | if (!headOrBody) { 16 | throw new Error( 17 | 'Expected document.body not to be null. Terminal requires a element.' 18 | ); 19 | } 20 | 21 | headOrBody.appendChild(script); 22 | 23 | return script; 24 | }; 25 | 26 | // TODO(jdivock): re-enable when we have a proper mechanism to track metrics 27 | 28 | // const registerWrapper = (stripe: any): void => { 29 | // if (!stripe || !stripe._registerWrapper) { 30 | // return; 31 | // } 32 | // 33 | // stripe._registerWrapper({name: 'terminal-js', version: _VERSION}); 34 | // }; 35 | 36 | let stripePromise: Promise | null = null; 37 | 38 | export const loadScript = (): Promise => { 39 | // Ensure that we only attempt to load Stripe.js at most once 40 | if (stripePromise !== null) { 41 | return stripePromise; 42 | } 43 | 44 | stripePromise = new Promise((resolve, reject) => { 45 | if (typeof window === 'undefined') { 46 | // Resolve to null when imported server side. This makes the module 47 | // safe to import in an isomorphic code base. 48 | resolve(null); 49 | return; 50 | } 51 | 52 | if (window.StripeTerminal) { 53 | resolve(window.StripeTerminal); 54 | return; 55 | } 56 | 57 | const script: HTMLScriptElement = 58 | document.querySelector( 59 | `script[src="${V1_URL}"], script[src="${V1_URL}/"]` 60 | ) || injectScript(); 61 | 62 | script.addEventListener('load', () => { 63 | if (window.StripeTerminal) { 64 | resolve(window.StripeTerminal); 65 | } else { 66 | reject(new Error('StripeTerminal not available')); 67 | } 68 | }); 69 | 70 | script.addEventListener('error', () => { 71 | reject(new Error('Failed to load StripeTerminal')); 72 | }); 73 | }); 74 | 75 | return stripePromise; 76 | }; 77 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stripe/terminal-js", 3 | "version": "0.26.0", 4 | "description": "Stripe Terminal loading utility", 5 | "main": "dist/terminal.js", 6 | "module": "dist/terminal.esm.js", 7 | "jsnext:main": "dist/terminal.esm.js", 8 | "types": "types/index.d.ts", 9 | "scripts": { 10 | "test": "./node_modules/.bin/jest", 11 | "test:versions": "./tests/versions/scripts/test.sh", 12 | "test:types": "./node_modules/.bin/tsc -p ./tests/types && ./node_modules/.bin/jest --roots '/tests/types'", 13 | "lint": "./node_modules/.bin/eslint '{src,types}/**/*.{ts,js}' && yarn prettier-list-different", 14 | "typecheck": "./node_modules/.bin/tsc", 15 | "build": "yarn clean && yarn rollup -c", 16 | "clean": "./node_modules/.bin/rimraf dist", 17 | "ci": "yarn lint && yarn test && yarn test:versions && yarn test:types && yarn typecheck && yarn build", 18 | "prepublishOnly": "echo \"\nPlease use ./scripts/publish instead\n\" && exit 1", 19 | "prettier": "./node_modules/.bin/prettier './**/*.{js,ts,md,html,css}' --write", 20 | "prettier-list-different": "./node_modules/.bin/prettier './**/*.{js,ts,md,html,css}' --list-different" 21 | }, 22 | "keywords": [ 23 | "Stripe", 24 | "Terminal", 25 | "Terminal.js" 26 | ], 27 | "author": "Stripe (https://www.stripe.com)", 28 | "license": "MIT", 29 | "homepage": "https://stripe.com/docs/terminal/sdk/js", 30 | "files": [ 31 | "dist", 32 | "src", 33 | "types", 34 | "pure.js", 35 | "pure.d.ts" 36 | ], 37 | "devDependencies": { 38 | "@babel/core": "^7.7.2", 39 | "@babel/preset-env": "^7.7.1", 40 | "@rollup/plugin-replace": "^2.3.1", 41 | "@types/jest": "^26.0.3", 42 | "@typescript-eslint/eslint-plugin": "^5.2.0", 43 | "@typescript-eslint/parser": "^5.2.0", 44 | "babel-eslint": "^10.1.0", 45 | "babel-jest": "^27.3.1", 46 | "conditional-type-checks": "^1.0.5", 47 | "eslint": "^8.1.0", 48 | "eslint-config-prettier": "^8.3.0", 49 | "eslint-plugin-import": "^2.25.2", 50 | "eslint-plugin-jest": "^25.2.2", 51 | "eslint-plugin-prettier": "^4.0.0", 52 | "jest": "^27.0.4", 53 | "prettier": "^1.19.1", 54 | "protobufjs": "^7.2.4", 55 | "rimraf": "^2.6.2", 56 | "rollup": "^2.79.2", 57 | "rollup-plugin-babel": "^4.3.3", 58 | "rollup-plugin-typescript2": "^0.25.3", 59 | "ts-jest": "^27.0.3", 60 | "typescript": "^3.7.4" 61 | }, 62 | "dependencies": { 63 | "stripe": "^8.222.0", 64 | "ws": "6.2.3" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /scripts/publish: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | RELEASE_TYPE=${1:-} 7 | 8 | echo_help() { 9 | cat << EOF 10 | USAGE: 11 | ./scripts/publish 12 | 13 | ARGS: 14 | 15 | A Semantic Versioning release type used to bump the version number. Either "patch", "minor", or "major". 16 | EOF 17 | } 18 | 19 | create_github_release() { 20 | if ! command -v hub &> /dev/null 21 | then 22 | create_github_release_fallback 23 | return 24 | fi 25 | 26 | # Get the last two releases. For example, `("v1.3.1" "v1.3.2")` 27 | local versions=($(git tag --sort version:refname | grep '^v' | tail -n 2)) 28 | 29 | # If we didn't find exactly two previous version versions, give up 30 | if [ ${#versions[@]} -ne 2 ]; then 31 | create_github_release_fallback 32 | return 33 | fi 34 | 35 | local previous_version="${versions[0]}" 36 | local current_version="${versions[1]}" 37 | local commit_titles=$(git log --pretty=format:"- %s" "$previous_version".."$current_version"^) 38 | local release_notes="$(cat << EOF 39 | $current_version 40 | 41 | 42 | 43 | 44 | $commit_titles 45 | 46 | ### New features 47 | 48 | ### Fixes 49 | 50 | ### Changed 51 | 52 | EOF 53 | )" 54 | 55 | echo "Creating GitHub release" 56 | echo "" 57 | echo -n " " 58 | hub release create -em "$release_notes" "$current_version" 59 | } 60 | 61 | create_github_release_fallback() { 62 | cat << EOF 63 | Remember to create a release on GitHub with a changelog notes: 64 | 65 | https://github.com/stripe/terminal-js/releases/new 66 | 67 | EOF 68 | } 69 | 70 | # Show help if no arguments passed 71 | if [ $# -eq 0 ]; then 72 | echo "Error! Missing release type argument" 73 | echo "" 74 | echo_help 75 | exit 1 76 | fi 77 | 78 | # Show help message if -h, --help, or help passed 79 | case $1 in 80 | -h | --help | help) 81 | echo_help 82 | exit 0 83 | ;; 84 | esac 85 | 86 | # Validate passed release type 87 | case $RELEASE_TYPE in 88 | patch | minor | major) 89 | ;; 90 | 91 | *) 92 | echo "Error! Invalid release type supplied" 93 | echo "" 94 | echo_help 95 | exit 1 96 | ;; 97 | esac 98 | 99 | # Make sure our working dir is the repo root directory 100 | cd "$(git rev-parse --show-toplevel)" 101 | 102 | echo "Fetching git remotes" 103 | git fetch 104 | 105 | GIT_STATUS=$(git status) 106 | 107 | if ! grep -q 'On branch master' <<< "$GIT_STATUS"; then 108 | echo "Error! Must be on master branch to publish" 109 | exit 1 110 | fi 111 | 112 | if ! grep -q "Your branch is up to date with 'origin/master'." <<< "$GIT_STATUS"; then 113 | echo "Error! Must be up to date with origin/master to publish" 114 | exit 1 115 | fi 116 | 117 | if ! grep -q 'working tree clean' <<< "$GIT_STATUS"; then 118 | echo "Error! Cannot publish with dirty working tree" 119 | exit 1 120 | fi 121 | 122 | echo "Installing dependencies according to lockfile" 123 | yarn -s install --frozen-lockfile 124 | 125 | echo "Linting, testing, and building" 126 | yarn -s run ci 127 | 128 | echo "Tagging and publishing $RELEASE_TYPE release" 129 | yarn -s --ignore-scripts publish --$RELEASE_TYPE --access=public 130 | 131 | echo "Pushing git commit and tag" 132 | git push --follow-tags 133 | 134 | echo "Publish successful!" 135 | echo "" 136 | 137 | create_github_release 138 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Terminal JS ES Module 2 | 3 | Use the [Terminal JS SDK](https://stripe.com/docs/terminal/sdk/js) as an ES 4 | module. 5 | 6 | **Note**: This package dynamically loads the Stripe Terminal SDK from 7 | `https://js.stripe.com` and wraps the SDK's global`StripeTerminal` function. To 8 | be 9 | [PCI compliant](https://stripe.com/docs/security/guide#validating-pci-compliance), 10 | you must load the SDK directly from `https://js.stripe.com` by using this 11 | library. You cannot include the dynamically loaded code in a bundle or host it 12 | yourself. 13 | 14 | [![npm version](https://img.shields.io/npm/v/@stripe/terminal-js.svg?style=flat-square)](https://www.npmjs.com/package/@stripe/terminal-js) 15 | 16 | ## Installation 17 | 18 | Use `npm` or `yarn` to install the Terminal JS module: 19 | 20 | ```sh 21 | > npm install @stripe/terminal-js 22 | 23 | > yarn add @stripe/terminal-js 24 | ``` 25 | 26 | ## Usage 27 | 28 | ### `loadStripeTerminal` 29 | 30 | This function returns a `Promise` that resolves with a newly created 31 | `StripeTerminal` object once the Terminal JS SDK has loaded. If necessary, it 32 | will load the SDK for you by inserting the Terminal JS script tag. If you call 33 | `loadStripeTerminal` in a server environment it will resolve to `null`. 34 | 35 | ```js 36 | import {loadStripeTerminal} from '@stripe/terminal-js'; 37 | 38 | const StripeTerminal = await loadStripeTerminal(); 39 | 40 | const terminal = StripeTerminal.create({ 41 | onFetchConnectionToken: async () => { 42 | … 43 | } 44 | }) 45 | ``` 46 | 47 | For more information on how to use the Terminal JS SDK once it loads, please 48 | refer to the 49 | [Terminal JS SDK API reference](https://stripe.com/docs/terminal/js-api-reference) 50 | or follow our [getting started](https://stripe.com/docs/terminal/sdk/js) guide. 51 | 52 | ## TypeScript support 53 | 54 | This package includes TypeScript declarations for the Terminal JS SDK. We 55 | support projects using TypeScript versions >= 3.1. 56 | 57 | Some methods in Terminal JS SDK accept and return objects from the 58 | [Stripe API](https://stripe.com/docs/api). The type declarations in 59 | `@stripe/terminal-js` for these objects in currently track to 60 | [version 2018-08-23](https://stripe.com/docs/api/versioning) of the Stripe API. 61 | If you have code using other versions of the Stripe API you may have to override 62 | type definitions as necessary. 63 | 64 | Note that we may release new [minor and patch](https://semver.org/) versions of 65 | `@stripe/terminal-js` with small but backwards-incompatible fixes to the type 66 | declarations. These changes will not affect the Terminal JS SDK itself. 67 | 68 | ## Ensuring the Terminal JS SDK is available everywhere 69 | 70 | By default, this module will insert a ` 93 | ``` 94 | 95 | ### Importing `loadStripeTerminal` without side effects 96 | 97 | If you would like to use `loadStripeTerminal` in your application, but defer 98 | loading the Terminal JS SDK script until `loadStripeTerminal` is first called, 99 | use the alternative `@stripe/terminal-js/pure` import path: 100 | 101 | ``` 102 | import {loadStripeTerminal} from '@stripe/terminal-js/pure'; 103 | 104 | // Terminal SDK will not be loaded until `loadStripeTerminal` is called 105 | ``` 106 | 107 | ## Terminal JS SDK Documentation 108 | 109 | - [Terminal JS SDK Docs](https://stripe.com/docs/terminal/sdk/js) 110 | - [Terminal JS SDK API Reference](https://stripe.com/docs/terminal/js-api-reference) 111 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | 3 | const dispatchScriptEvent = (eventType: string): void => { 4 | const injectedScript = document.querySelector( 5 | 'script[src="https://js.stripe.com/terminal/v1"]' 6 | ); 7 | 8 | if (!injectedScript) { 9 | throw new Error('could not find StripeTerminal script element'); 10 | } 11 | 12 | injectedScript.dispatchEvent(new Event(eventType)); 13 | }; 14 | 15 | describe('Stripe module loader', () => { 16 | afterEach(() => { 17 | const script = document.querySelector( 18 | 'script[src="https://js.stripe.com/terminal/v1"], script[src="https://js.stripe.com/terminal/v1/"]' 19 | ); 20 | if (script && script.parentElement) { 21 | script.parentElement.removeChild(script); 22 | } 23 | delete window.StripeTerminal; 24 | jest.resetModules(); 25 | }); 26 | 27 | it('injects the Terminal script as a side effect after a tick', () => { 28 | require('./index'); 29 | 30 | expect( 31 | document.querySelector('script[src="https://js.stripe.com/terminal/v1"]') 32 | ).toBe(null); 33 | 34 | return Promise.resolve().then(() => { 35 | expect( 36 | document.querySelector( 37 | 'script[src="https://js.stripe.com/terminal/v1"]' 38 | ) 39 | ).not.toBe(null); 40 | }); 41 | }); 42 | 43 | it('does not inject the script when Stripe is already loaded', () => { 44 | require('./index'); 45 | 46 | window.StripeTerminal = jest.fn((key) => ({key})) as any; 47 | 48 | return new Promise((resolve) => setTimeout(resolve)).then(() => { 49 | expect( 50 | document.querySelector( 51 | 'script[src="https://js.stripe.com/terminal/v1"]' 52 | ) 53 | ).toBe(null); 54 | }); 55 | }); 56 | 57 | describe('does not inject a duplicate script when one is already present', () => { 58 | test('when the script does not have a trailing slash', () => { 59 | require('./index'); 60 | 61 | const script = document.createElement('script'); 62 | script.src = 'https://js.stripe.com/terminal/v1'; 63 | document.body.appendChild(script); 64 | 65 | return Promise.resolve().then(() => { 66 | expect( 67 | document.querySelectorAll( 68 | 'script[src="https://js.stripe.com/terminal/v1"], script[src="https://js.stripe.com/terminal/v1/"]' 69 | ) 70 | ).toHaveLength(1); 71 | }); 72 | }); 73 | 74 | test('when the script has a trailing slash', () => { 75 | require('./index'); 76 | 77 | const script = document.createElement('script'); 78 | script.src = 'https://js.stripe.com/terminal/v1/'; 79 | document.body.appendChild(script); 80 | 81 | return Promise.resolve().then(() => { 82 | expect( 83 | document.querySelectorAll( 84 | 'script[src="https://js.stripe.com/terminal/v1"], script[src="https://js.stripe.com/terminal/v1/"]' 85 | ) 86 | ).toHaveLength(1); 87 | }); 88 | }); 89 | }); 90 | 91 | describe.each(['./index', './pure'])( 92 | 'loadStripeTerminal (%s.ts)', 93 | (requirePath) => { 94 | beforeEach(() => { 95 | jest.restoreAllMocks(); 96 | jest.spyOn(console, 'warn').mockReturnValue(); 97 | }); 98 | 99 | it('resolves loadStripeTerminal with Terminal object', async () => { 100 | const {loadStripeTerminal} = require(requirePath); 101 | const stripePromise = loadStripeTerminal(); 102 | 103 | await new Promise((resolve) => setTimeout(resolve)); 104 | window.StripeTerminal = jest.fn() as any; 105 | dispatchScriptEvent('load'); 106 | 107 | return expect(stripePromise).resolves.toBeDefined(); 108 | }); 109 | 110 | it('rejects when the script fails', async () => { 111 | const {loadStripeTerminal} = require(requirePath); 112 | const stripePromise = loadStripeTerminal(); 113 | 114 | await Promise.resolve(); 115 | dispatchScriptEvent('error'); 116 | 117 | await expect(stripePromise).rejects.toEqual( 118 | new Error('Failed to load StripeTerminal') 119 | ); 120 | 121 | expect(console.warn).not.toHaveBeenCalled(); 122 | }); 123 | 124 | it('rejects when Terminal is not added to the window for some reason', async () => { 125 | const {loadStripeTerminal} = require(requirePath); 126 | const stripePromise = loadStripeTerminal(); 127 | 128 | await Promise.resolve(); 129 | dispatchScriptEvent('load'); 130 | 131 | return expect(stripePromise).rejects.toEqual( 132 | new Error('StripeTerminal not available') 133 | ); 134 | }); 135 | } 136 | ); 137 | 138 | describe('loadStripeTerminal (index.ts)', () => { 139 | it('does not cause unhandled rejects when the script fails', async () => { 140 | require('./index'); 141 | 142 | await Promise.resolve(); 143 | dispatchScriptEvent('error'); 144 | 145 | // Turn the task loop to make sure the internal promise handler has been invoked 146 | await new Promise((resolve) => setTimeout(resolve, 0)); 147 | 148 | expect(console.warn).toHaveBeenCalledWith( 149 | new Error('Failed to load StripeTerminal') 150 | ); 151 | }); 152 | }); 153 | }); 154 | -------------------------------------------------------------------------------- /types/terminal.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | import Stripe from 'stripe'; 3 | 4 | import { 5 | IActivateTerminalRequest, 6 | IErrorResponse, 7 | IPaymentMethod as SdkIPaymentMethod, 8 | IPaymentMethodReadReusableResponse, 9 | IRefundChargeRequest, 10 | ISetReaderDisplayRequest, 11 | ITipConfiguration, 12 | IRefund, 13 | IPaymentIntentExpandedMethod, 14 | IReaderSettings, 15 | ISetReaderSettingsRequest, 16 | IAccessibilitySettings, 17 | IAccessibilityParameters, 18 | ITextToSpeechStatus, 19 | } from './proto'; 20 | 21 | export { 22 | IActivateTerminalRequest, 23 | IErrorResponse, 24 | IPaymentMethodReadReusableResponse, 25 | IPaymentMethod, 26 | IRefundChargeRequest, 27 | ISetReaderDisplayRequest, 28 | ITipConfiguration, 29 | IRefund, 30 | IReaderSettings, 31 | ISetReaderSettingsRequest, 32 | IAccessibilitySettings, 33 | IAccessibilityParameters, 34 | ITextToSpeechStatus, 35 | }; 36 | 37 | export enum PaymentStatus { 38 | NOT_READY = 'not_ready', 39 | READY = 'ready', 40 | WAITING_FOR_INPUT = 'waiting_for_input', 41 | PROCESSING = 'processing', 42 | } 43 | 44 | export enum ConnectionStatus { 45 | CONNECTING = 'connecting', 46 | CONNECTED = 'connected', 47 | NOT_CONNECTED = 'not_connected', 48 | } 49 | 50 | export enum OutputLogLevel { 51 | NONE = 'none', 52 | VERBOSE = 'verbose', 53 | } 54 | 55 | export enum AllowRedisplay { 56 | ALWAYS = 'always', 57 | LIMITED = 'limited', 58 | UNSPECIFIED = 'unspecified', 59 | } 60 | 61 | export declare type ConnectionToken = string; 62 | export declare type FetchConnectionTokenFn = () => Promise; 63 | 64 | export declare type ISetReaderDisplayResponse = Record; 65 | export declare type ICancelResponse = Record; 66 | export declare type IClearCachedCredentialsResponse = Record; 67 | export declare type IClearReaderDisplayResponse = Record; 68 | export declare type ICollectRefundPaymentMethodResponse = Record; 69 | export declare type IDisconnectResponse = Record; 70 | export declare type IPrintResponse = Record; 71 | 72 | interface IPaymentMethod extends SdkIPaymentMethod { 73 | payment_intent?: IPaymentIntentExpandedMethod | null; 74 | } 75 | 76 | export interface StatusEvent { 77 | status: T; 78 | } 79 | export interface DisconnectEvent { 80 | error?: ExposedError; 81 | } 82 | export declare type ConnectionStatusEvent = StatusEvent; 83 | export declare type PaymentStatusEvent = StatusEvent; 84 | export declare type EventHandler = (event: T) => void; 85 | export interface TerminalCallbacks { 86 | onFetchConnectionToken: FetchConnectionTokenFn; 87 | onUnexpectedReaderDisconnect?: EventHandler; 88 | onConnectionStatusChange?: EventHandler; 89 | onPaymentStatusChange?: EventHandler; 90 | } 91 | export interface ReaderBehaviors { 92 | allowCustomerCancel?: boolean; 93 | } 94 | export interface TerminalOptions { 95 | logLevel?: OutputLogLevel; 96 | simulatorBaseUrl?: string; 97 | readerBehavior?: ReaderBehaviors; 98 | } 99 | export declare type TerminalProps = TerminalOptions & TerminalCallbacks; 100 | 101 | export declare type PaymentIntentClientSecret = string; 102 | 103 | export declare type DeviceType = Stripe.Terminal.Reader.DeviceType; 104 | 105 | export declare type Reader = Stripe.Terminal.Reader; 106 | 107 | export declare type IPaymentIntent = Stripe.PaymentIntent; 108 | export declare type ISetupIntent = Stripe.SetupIntent; 109 | 110 | export interface ISdkManagedPaymentIntent extends IPaymentIntent { 111 | sdk_payment_details: IPaymentMethod; 112 | } 113 | export type SdkManagedPaymentIntent = ISdkManagedPaymentIntent; 114 | 115 | export interface ICollectConfig { 116 | // Bypass tipping selection if it would have otherwise been shown. 117 | // For more information, see the official Stripe docs: [On Reader Tipping](https://stripe.com/docs/terminal/features/collecting-tips/on-reader) 118 | skip_tipping?: boolean | null; 119 | tipping?: ITippingConfig | null; 120 | // set to true to return the expanded payment_intent. 121 | update_payment_intent?: boolean | null; 122 | 123 | // the ID of the payment intent to return back. 124 | payment_intent_id?: string | null; 125 | 126 | // Optional notice to display on the payment collection screen to inform the customer of a surcharge. 127 | surcharge_notice?: string | null; 128 | 129 | // Request ability to offer dynamic currency conversion (DCC) if the card is eligible. 130 | request_dynamic_currency_conversion?: boolean | null; 131 | 132 | // Required if `setup_future_usage` is set; otherwise, it defaults to `unspecified`. 133 | // An enum value indicating whether future checkout flows can show this payment method to its customer. 134 | allow_redisplay?: AllowRedisplay | null; 135 | 136 | // Collect and process the payment as a Mail Order/Telephone Order payment. Contact Stripe support to enable this feature on your account. 137 | // For more information, see the official Stripe docs: [Mail Order Telephone Order transactions](https://support.stripe.com/questions/mail-order-telephone-order-(moto)-transactions-when-to-categorize-transactions-as-moto) 138 | moto?: boolean | null; 139 | } 140 | 141 | // Contains per-transaction configuration information relevant to collecting tips 142 | export interface ITippingConfig { 143 | // Calculate percentage-based tips based on this amount. 144 | // For more information, see the official Stripe docs: [On Reader Tipping](https://stripe.com/docs/terminal/features/collecting-tips/on-reader) 145 | eligible_amount?: number | null; 146 | } 147 | 148 | // Whether to collect surcharge consent from the customer. 149 | export enum SurchargeConsentCollection { 150 | ENABLED = 'enabled', 151 | DISABLED = 'disabled', 152 | } 153 | 154 | // Configuration information relevant to displaying surcharge consent to the customer. 155 | export interface ISurchargeConsent { 156 | // Whether to collect surcharge consent from the customer. 157 | collection: SurchargeConsentCollection; 158 | // Display a custom message on the surcharge consent screen to the customer. 159 | notice?: string | null; 160 | } 161 | 162 | export interface ISurchargeConfiguration { 163 | // Amount surcharge to apply to the transaction. Must be a positive non-zero number 164 | amount: number; 165 | // Configuration for the surcharge consent. 166 | consent: ISurchargeConsent; 167 | } 168 | // Contains configuration information relevant to processing/confirming a payment method. 169 | export interface IProcessConfig { 170 | // [Deprecated in favor of surcharge.amount] Surcharge amount to be applied to the payment. 171 | amount_surcharge?: number | null; 172 | 173 | // The URL to redirect your customer back to after they authenticate or cancel their payment on the payment method’s app or site. 174 | // If you’d prefer to redirect to a mobile application, you can alternatively supply an application URI scheme. 175 | // This parameter is only used for redirect-based payment methods. 176 | return_url?: string | null; 177 | 178 | // Configuration for the surcharge. 179 | surcharge?: ISurchargeConfiguration | null; 180 | } 181 | 182 | // Contains configuration information relevant to collecting a setup intent. 183 | export interface ISetupIntentConfig { 184 | // Whether to show a cancel button in transaction UI on Stripe smart readers. 185 | enable_customer_cancellation?: boolean | null; 186 | 187 | // Save the payment method using the Mail Order/Telephone Order feature. Contact Stripe support to enable this feature on your account. 188 | // For more information, see the official Stripe docs: [Mail Order Telephone Order transactions](https://support.stripe.com/questions/mail-order-telephone-order-(moto)-transactions-when-to-categorize-transactions-as-moto) 189 | moto?: boolean | null; 190 | } 191 | 192 | export declare type ConnectOptions = Pick< 193 | IActivateTerminalRequest, 194 | 'fail_if_in_use' 195 | >; 196 | export declare type RefundOptions = Pick< 197 | IRefundChargeRequest, 198 | 'reverse_transfer' | 'refund_application_fee' 199 | >; 200 | 201 | export declare type ErrorResponse = { 202 | error: ExposedError; 203 | }; 204 | export declare type ExposedError = { 205 | type?: string; 206 | request_id?: string; 207 | code?: string; 208 | message: string; 209 | decline_code?: string; 210 | payment_intent?: IPaymentIntent; 211 | failure_reason?: string; 212 | failure_balance_transaction?: string; 213 | }; 214 | 215 | export enum SimulatedCollectInputsResultType { 216 | SUCCEEDED = 'succeeded', 217 | TIMEOUT = 'timeout', 218 | } 219 | 220 | export interface ISimulatedCollectInputsResult { 221 | resultType: SimulatedCollectInputsResultType; 222 | } 223 | 224 | export enum SimulatedCollectInputsSkipBehavior { 225 | NONE = 'none', 226 | ALL = 'all', 227 | } 228 | 229 | export interface ISimulatedCollectInputsResultSucceeded 230 | extends ISimulatedCollectInputsResult { 231 | skipBehavior: SimulatedCollectInputsSkipBehavior; 232 | } 233 | 234 | export interface ISimulatedCollectInputsResultTimeout 235 | extends ISimulatedCollectInputsResult {} 236 | 237 | export interface SimulatorConfiguration { 238 | paymentMethodType?: 'interac_present' | null; 239 | testPaymentMethod?: string | null; 240 | testCardNumber?: string | null; 241 | tipAmount?: number | null; 242 | collectInputsResult?: ISimulatedCollectInputsResult | null; 243 | } 244 | 245 | export interface DiscoveryMethodConfiguration { 246 | device_type?: string; 247 | method?: string; 248 | simulated?: boolean; 249 | } 250 | export interface InternetMethodConfiguration 251 | extends DiscoveryMethodConfiguration { 252 | method?: 'internet'; 253 | location?: string; 254 | } 255 | export declare type DiscoveryConfig = InternetMethodConfiguration; 256 | export declare type DiscoverResult = { 257 | discoveredReaders: Array; 258 | }; 259 | 260 | export type Address = Stripe.Address; 261 | 262 | export type Location = Stripe.Terminal.Location; 263 | 264 | // Contains information about the inputs to collect from the reader 265 | export interface ICollectInputsParameters { 266 | inputs: Array; 267 | } 268 | 269 | export enum FormType { 270 | SELECTION = 'selection', 271 | SIGNATURE = 'signature', 272 | PHONE = 'phone', 273 | EMAIL = 'email', 274 | NUMERIC = 'numeric', 275 | TEXT = 'text', 276 | } 277 | 278 | // Represents a single input form 279 | export interface IInput { 280 | // Set the type of the form 281 | formType: FormType; 282 | 283 | // Set whether this form is required 284 | required?: boolean | null; 285 | 286 | // Set the title of the form 287 | title: string; 288 | 289 | // Set the description of the form 290 | description?: string | null; 291 | 292 | // Set the toggles to display on the form 293 | toggles?: IToggle[] | null; 294 | 295 | // Modify the skip button text 296 | skipButtonText?: string | null; 297 | } 298 | 299 | // Represents the toggle state 300 | export enum ToggleValue { 301 | // Toggle is checked or on 302 | ENABLED = 'enabled', 303 | // Toggle is unchecked or off 304 | DISABLED = 'disabled', 305 | } 306 | 307 | // Contains information for a collect inputs toggle 308 | export interface IToggle { 309 | // Set the main, larger style text. 310 | title?: string | null; 311 | // Set the secondary, smaller style text. 312 | description?: string | null; 313 | // Set the initial value to be set for the toggle. 314 | defaultValue: ToggleValue; 315 | } 316 | 317 | // Represents the style of a selection form button 318 | export enum SelectionButtonStyle { 319 | // Button will use a highlighted, accent color 320 | PRIMARY = 'primary', 321 | // Button will use a subdued, secondary color 322 | SECONDARY = 'secondary', 323 | } 324 | 325 | // Contains information for a selection form button 326 | export interface ISelectionButton { 327 | // Set the style of a selection button 328 | style: SelectionButtonStyle; 329 | // Set the button text 330 | text: string; 331 | // Set the button id 332 | id: string; 333 | } 334 | 335 | // Contains information about a selection form to display on the reader 336 | export interface SelectionInput extends IInput { 337 | // Set the button choices to display on the form 338 | selectionButtons: ISelectionButton[]; 339 | } 340 | 341 | // Contains information about a signature form to display on the reader 342 | export interface SignatureInput extends IInput { 343 | // Modify the submit button text 344 | submitButtonText?: string | null; 345 | } 346 | 347 | // Contains information about a phone form to display on the reader 348 | export interface PhoneInput extends IInput { 349 | // Modify the submit button text 350 | submitButtonText?: string | null; 351 | } 352 | 353 | // Contains information about an email form to display on the reader 354 | export interface EmailInput extends IInput { 355 | // Modify the submit button text 356 | submitButtonText?: string | null; 357 | } 358 | 359 | // Contains information about a text form to display on the reader 360 | export interface TextInput extends IInput { 361 | // Modify the submit button text 362 | submitButtonText?: string | null; 363 | } 364 | 365 | // Contains information about a numeric form to display on the reader 366 | export interface NumericInput extends IInput { 367 | // Modify the submit button text 368 | submitButtonText?: string | null; 369 | } 370 | 371 | // Contains data collected for a toggle 372 | export enum ToggleResult { 373 | // Toggle is unchecked or off 374 | DISABLED = 'disabled', 375 | // Toggle is checked or on 376 | ENABLED = 'enabled', 377 | // Input form is skipped, no value 378 | SKIPPED = 'skipped', 379 | } 380 | 381 | // Contains the common fields for all input result types 382 | export interface ICollectInputsResult { 383 | // the type of the form 384 | formType: FormType; 385 | 386 | // if true, the skip button was pressed to skip the form. 387 | skipped: boolean; 388 | 389 | // array of toggles and selected value. Values are `ToggleResult.SKIPPED` if form was skipped. 390 | toggles: ToggleResult[]; 391 | } 392 | 393 | // Contains data collected from a selection form 394 | export interface SelectionResult extends ICollectInputsResult { 395 | // selected button. Null if the form was skipped. 396 | selection?: string | null; 397 | // selected button ID. Null if the form was skipped. 398 | selectionId?: string | null; 399 | } 400 | 401 | // Contains data collected from a signature form 402 | export interface SignatureResult extends ICollectInputsResult { 403 | // signature in svg format. Null if the form was skipped. 404 | signatureSvg?: string | null; 405 | } 406 | 407 | // Contains data collected from a phone form 408 | export interface PhoneResult extends ICollectInputsResult { 409 | // the submitted phone number in E.164 format. Null if the form was skipped. 410 | phone?: string | null; 411 | } 412 | 413 | // Contains data collected from an email form 414 | export interface EmailResult extends ICollectInputsResult { 415 | // the submitted email. Null if the form was skipped. 416 | email?: string | null; 417 | } 418 | 419 | // Contains data collected from a text form 420 | export interface TextResult extends ICollectInputsResult { 421 | // the submitted text. Null if the form was skipped. 422 | text?: string | null; 423 | } 424 | 425 | // Contains data collected from an email form 426 | export interface NumericResult extends ICollectInputsResult { 427 | // the submitted number as a string. Null if the form was skipped. 428 | numericString?: string | null; 429 | } 430 | 431 | // Represents the content to print to a reader's embedded printer. 432 | export type IPrintContent = HTMLCanvasElement; 433 | 434 | export class Terminal { 435 | /** 436 | * Returns the current connection status of the PIN pad. 437 | */ 438 | getConnectionStatus(): ConnectionStatus; 439 | /** 440 | * Returns the current transaction status. 441 | */ 442 | getPaymentStatus(): PaymentStatus; 443 | /** 444 | * Returns a promise that resolves with discovered readers that can be connected to. 445 | */ 446 | discoverReaders( 447 | config?: DiscoveryConfig 448 | ): Promise; 449 | /** 450 | * Returns a promise that resolves only when the SDK has connected to a Reader. 451 | */ 452 | connectReader( 453 | reader: Reader, 454 | connectOptions?: ConnectOptions 455 | ): Promise< 456 | | ErrorResponse 457 | | { 458 | reader: Reader; 459 | } 460 | >; 461 | /** 462 | * Returns the current connected reader. 463 | */ 464 | getConnectedReader(): Reader; 465 | /** 466 | * Disconnects from any connected Readers and triggers reconnecting based on 467 | * the options in the passed in config. 468 | */ 469 | disconnectReader(): Promise; 470 | /** 471 | * Clears the cached connection token or rabbit sessions 472 | */ 473 | clearCachedCredentials(): Promise< 474 | IClearCachedCredentialsResponse | ErrorResponse 475 | >; 476 | /** 477 | * Ends the Checkout Flow. This brings the UX back to the splash screen. 478 | */ 479 | clearReaderDisplay(): Promise; 480 | /** 481 | * Updates the PIN Pad UI with information on the basket the user is buying 482 | * @param request Request object containing information on the basket 483 | */ 484 | setReaderDisplay( 485 | request: ISetReaderDisplayRequest 486 | ): Promise; 487 | /** 488 | * Display forms and collect information from customers. Available for BBPOS WisePOS E and Stripe S700. 489 | * @param collectInputsParameters Parameters to configure forms 490 | */ 491 | collectInputs( 492 | collectInputsParameters: ICollectInputsParameters 493 | ): Promise>; 494 | /** 495 | * Cancels an in-flight request made by collectInputs 496 | */ 497 | cancelCollectInputs(): Promise; 498 | /** 499 | * Requests the Terminal object to collect a card source from the reader that 500 | * can be charged. 501 | * @param request Request object containing the payment intent secret of the intent to attach the 502 | * source to. 503 | */ 504 | collectPaymentMethod( 505 | request: PaymentIntentClientSecret, 506 | options?: { 507 | tip_configuration?: ITipConfiguration; 508 | config_override?: ICollectConfig; 509 | } 510 | ): Promise< 511 | | ErrorResponse 512 | | { 513 | paymentIntent: ISdkManagedPaymentIntent; 514 | } 515 | >; 516 | cancelCollectPaymentMethod(): Promise; 517 | /** 518 | * Confirms the payment intent which causes the charging of the user card. 519 | * @param request Object containing the payment intent to confirm. 520 | */ 521 | processPayment( 522 | request: ISdkManagedPaymentIntent, 523 | options?: { 524 | config_override?: IProcessConfig; 525 | } 526 | ): Promise< 527 | | ErrorResponse 528 | | { 529 | paymentIntent: IPaymentIntent; 530 | } 531 | >; 532 | cancelProcessPayment(): Promise; 533 | readReusableCard(options?: { 534 | customer?: string; 535 | }): Promise< 536 | | ErrorResponse 537 | | { 538 | payment_method: IPaymentMethodReadReusableResponse; 539 | } 540 | >; 541 | 542 | /** 543 | * Requests the Terminal object to collect a card source from the reader that 544 | * can be saved via a SetupIntent. 545 | * @param clientSecret Request object containing the setup intent secret of the intent to attach The 546 | * @param customerConsentCollectedOrAllowRedisplay field indicating whether this payment method can be shown again to its customer in a checkout flow. 547 | * @param config an optional object containing collection configuration. 548 | */ 549 | collectSetupIntentPaymentMethod( 550 | clientSecret: string, 551 | customerConsentCollectedOrAllowRedisplay: boolean | AllowRedisplay, 552 | config: ISetupIntentConfig | null 553 | ): Promise; 554 | 555 | /** 556 | * Cancels an in-flight request made by collectSetupIntentPaymentMethod to collect a payment method for future use 557 | */ 558 | cancelCollectSetupIntentPaymentMethod(): Promise< 559 | ErrorResponse | ICancelResponse 560 | >; 561 | 562 | /** 563 | * Confirms the setup intent which causes the card to be saved for future use. 564 | * @param setupIntent The SetupIntent object to confirm; use the value returned from collectSetupIntentPaymentMethod 565 | */ 566 | confirmSetupIntent( 567 | setupIntent: ISetupIntent 568 | ): Promise; 569 | cancelConfirmSetupIntent(): Promise; 570 | 571 | collectRefundPaymentMethod( 572 | charge_id: string, 573 | amount: number, 574 | currency: string, 575 | options?: RefundOptions 576 | ): Promise; 577 | cancelCollectRefundPaymentMethod(): Promise; 578 | 579 | processRefund(): Promise< 580 | | ErrorResponse 581 | | ErrorResponse 582 | | { 583 | refund: IRefund; 584 | } 585 | >; 586 | cancelProcessRefund(): Promise; 587 | 588 | cancelReadReusableCard(): Promise; 589 | setSimulatorConfiguration(config: any): void; 590 | getSimulatorConfiguration(): SimulatorConfiguration; 591 | overrideBaseURL(url: string): void; 592 | 593 | /** 594 | * Changes settings on the connected reader. 595 | * 596 | * @param request The request with the values to set on the reader. 597 | */ 598 | setReaderSettings( 599 | request: ISetReaderSettingsRequest 600 | ): Promise; 601 | 602 | /** 603 | * Retrieves current settings from the connected reader. 604 | */ 605 | getReaderSettings(): Promise; 606 | 607 | /** 608 | * Prints the specified content to the connected reader's printer, if available. 609 | * @param content The content to print. Currently only supports `HTMLCanvasElement`. 610 | */ 611 | print(content: IPrintContent): Promise; 612 | } 613 | -------------------------------------------------------------------------------- /types/proto.d.ts: -------------------------------------------------------------------------------- 1 | /** Properties of a RequestedCardPresent. */ 2 | interface IRequestedCardPresent { 3 | /** Type of card present information */ 4 | type?: string | null; 5 | 6 | /** Method used by POS to read the card */ 7 | read_method?: string | null; 8 | 9 | /** Reason for card swipe */ 10 | swipe_reason?: string | null; 11 | 12 | /** Encrypted or unencrypted track 2 data (depending on "type" field) */ 13 | track_2?: string | null; 14 | 15 | /** Processing method */ 16 | emv_processing_method?: string | null; 17 | 18 | /** Encrypted or unencrypted EMV data (depending on "type" field) */ 19 | emv_data?: string | null; 20 | 21 | /** The PIN block used in transactions backed by PIN */ 22 | pin_block?: string | null; 23 | 24 | /** Key Serial Number for the PIN block encryption */ 25 | pin_block_ksn?: string | null; 26 | 27 | /** Reader ID from activate */ 28 | reader?: string | null; 29 | 30 | /** Key type used to encrypt track_2 */ 31 | track_2_key_type?: string | null; 32 | 33 | /** Key ID of key used to encrypt track_2 */ 34 | track_2_key_id?: string | null; 35 | 36 | /** KSN used ot encrypt track_2 */ 37 | track_2_ksn?: string | null; 38 | } 39 | /** Properties of a RequestedPaymentMethod. */ 40 | interface IRequestedPaymentMethod { 41 | /** Type of payment method (e.g. "card_present") */ 42 | type?: string | null; 43 | 44 | /** Map of card present parameters */ 45 | card_present?: IRequestedCardPresent | null; 46 | 47 | /** Interac card present */ 48 | interac_present?: IRequestedCardPresent | null; 49 | } 50 | /** Properties of a RefundChargeRequest. */ 51 | interface IRefundChargeRequest { 52 | /** RefundChargeRequest charge */ 53 | charge?: string | null; 54 | 55 | /** RefundChargeRequest reason */ 56 | reason?: string | null; 57 | 58 | /** RefundChargeRequest refund_application_fee */ 59 | refund_application_fee?: boolean | null; 60 | 61 | /** RefundChargeRequest reverse_transfer */ 62 | reverse_transfer?: boolean | null; 63 | 64 | /** RefundChargeRequest payment_method_data */ 65 | payment_method_data?: IRequestedPaymentMethod | null; 66 | 67 | /** RefundChargeRequest amount */ 68 | amount?: number | null; 69 | } 70 | /** Properties of a TipOption. */ 71 | interface ITipOption { 72 | /** REQUIRED: Amount of this tip option */ 73 | amount?: number | null; 74 | 75 | /** Descriptor of the amount, displayed in the button */ 76 | label?: string | null; 77 | } 78 | /** Properties of a TipConfiguration. */ 79 | export interface ITipConfiguration { 80 | /** List of at most 3 options */ 81 | options?: ITipOption[] | null; 82 | 83 | /** Hide the custom amount button */ 84 | hide_custom_amount?: boolean | null; 85 | } 86 | /** Properties of a TipSelection. */ 87 | interface ITipSelection { 88 | /** Amount associated with the selection */ 89 | amount?: number | null; 90 | } 91 | /** CreditCardBrand enum. */ 92 | type CreditCardBrand = 93 | | 'INVALID_CREDIT_CARD_BRAND' 94 | | 'UNKNOWN_CREDIT' 95 | | 'AMERICAN_EXPRESS' 96 | | 'DINERS' 97 | | 'DISCOVER' 98 | | 'JCB' 99 | | 'MASTERCARD' 100 | | 'VISA' 101 | | 'CUP'; 102 | 103 | /** CardEntryMethod enum. */ 104 | type CardEntryMethod = 105 | | 'INVALID_ENTRY_METHOD' 106 | | 'CHIP_READ' 107 | | 'CONTACTLESS' 108 | | 'FSWIPE' 109 | | 'KEYED' 110 | | 'SWIPED' 111 | | 'BARCODE_READ'; 112 | /** Properties of a CardPaymentMethod. */ 113 | interface ICardPaymentMethod { 114 | /** Masked card data */ 115 | masked_pan?: string | null; 116 | 117 | /** The card expiration date */ 118 | expiration_date?: string | null; 119 | 120 | /** Brand of credit card tender, determined by BIN table lookup */ 121 | card_brand?: CreditCardBrand | null; 122 | 123 | /** Entry method of payment */ 124 | card_entry_method?: CardEntryMethod | null; 125 | } 126 | /** Properties of a PaymentMethod. */ 127 | export interface IPaymentMethod { 128 | /** PaymentMethod card_payment */ 129 | card_payment?: ICardPaymentMethod | null; 130 | 131 | /** Tip selection chosen by the cardholder */ 132 | tip_selection?: ITipSelection | null; 133 | } 134 | 135 | interface IPaymentIntentExpandedMethod { 136 | 137 | /** Unique identifier for the Payment Intent object */ 138 | id?: (string|null); 139 | 140 | /** Time at which the Payment Intent object was created. Measured in seconds since the Unix epoch */ 141 | created?: (number|null); 142 | 143 | /** Status of this PaymentIntent */ 144 | status?: (string|null); 145 | 146 | /** Amount intended to be collected by this Payment Intent */ 147 | amount?: (number|null); 148 | 149 | /** Three-letter ISO currency code, in lowercase. Must be a supported currency. */ 150 | currency?: (string|null); 151 | 152 | /** Card present payment source field map */ 153 | source?: (ISource|null); 154 | 155 | /** An arbitrary string to be displayed on your customer's credit card statement. */ 156 | statement_descriptor?: (string|null); 157 | 158 | /** An arbitrary string attached to the object. Often useful for displaying to users. */ 159 | description?: (string|null); 160 | 161 | /** Email address that the receipt for the resulting payment will be sent to. */ 162 | receipt_email?: (string|null); 163 | 164 | /** Whether this charge was made in live mode or not */ 165 | livemode?: (boolean|null); 166 | 167 | /** Last payment error on a charge (if retrieved) */ 168 | last_payment_error?: (IErrorResponse|null); 169 | 170 | /** Meta data in JSON format */ 171 | metadata?: ({ [k: string]: string }|null); 172 | 173 | /** Charges associated with the payment intent */ 174 | charges?: (ICharges|null); 175 | 176 | /** ID for payment method */ 177 | payment_method?: (IPaymentMethodReadReusableResponse|null); 178 | 179 | /** Amount that can be captured */ 180 | amount_capturable?: (number|null); 181 | 182 | /** Amount that was collected */ 183 | amount_received?: (number|null); 184 | 185 | /** The amount of the application fee (if any) for the resulting payment */ 186 | application_fee_amount?: (number|null); 187 | 188 | /** Populated when status is canceled, this is the time at which the PaymentIntent was canceled. */ 189 | canceled_at?: (number|null); 190 | 191 | /** Controls when the funds will be captured from the customer's account */ 192 | capture_method?: (Method|null); 193 | 194 | /** The client secret of this PaymentIntent. Used for client-side retrieval using a publishable key. */ 195 | client_secret?: (string|null); 196 | 197 | /** The confirmation method */ 198 | confirmation_method?: (Method|null); 199 | 200 | /** The customer of this payment intent */ 201 | customer?: (string|null); 202 | 203 | /** A string that identifies this intent as part of a group. */ 204 | transfer_group?: (string|null); 205 | } 206 | 207 | /** Properties of a PaymentMethod. */ 208 | export interface IPaymentMethodReadReusableResponse { 209 | /** Unique identifier for the Payment Method object */ 210 | id?: string | null; 211 | 212 | /** Time at which the Payment Method object was created. Measured in seconds since the Unix epoch */ 213 | created?: number | null; 214 | 215 | /** Customer ID */ 216 | customer?: string | null; 217 | 218 | /** Whether this charge was made in live mode or not */ 219 | livemode?: boolean | null; 220 | 221 | /** Meta data in JSON format */ 222 | metadata?: {[k: string]: string} | null; 223 | 224 | /** PaymentMethod type */ 225 | type?: string | null; 226 | 227 | /** Card representation of payment method */ 228 | card?: ICardPaymentMethodReadReusableResponse | null; 229 | } 230 | 231 | /** Properties of a CardPaymentMethod. */ 232 | interface ICardPaymentMethodReadReusableResponse { 233 | /** Masked card data */ 234 | masked_pan?: string | null; 235 | 236 | /** The card expiration date */ 237 | expiration_date?: string | null; 238 | 239 | /** Brand of credit card tender, determined by BIN table lookup */ 240 | card_brand?: CreditCardBrand | null; 241 | 242 | /** Entry method of payment */ 243 | card_entry_method?: CardEntryMethod | null; 244 | } 245 | 246 | /** Properties of an ErrorResponse. */ 247 | export interface IErrorResponse { 248 | /** The type of error returned. */ 249 | type?: string | null; 250 | 251 | /** ID of failed charge */ 252 | charge?: string | null; 253 | 254 | /** For some errors that could be handled programmatically, a short string indicating the error code reported. (https://stripe.com/docs/error-codes) */ 255 | code?: string | null; 256 | 257 | /** For card errors resulting from a card issuer decline, a short string indicating the card issuer’s reason for the decline if they provide one. (https://stripe.com/docs/declines#issuer-declines) */ 258 | decline_code?: string | null; 259 | 260 | /** A URL to more information about the error code reported. */ 261 | doc_url?: string | null; 262 | 263 | /** A human-readable message providing more details about the error. For card errors, these messages can be shown to your users. */ 264 | message?: string | null; 265 | 266 | /** If the error is parameter-specific, the parameter related to the error. For example, you can use this to display a message near the correct form field. */ 267 | param?: string | null; 268 | 269 | /** Source used for the error */ 270 | source?: ISource | null; 271 | 272 | /** Payment intent used for the error */ 273 | payment_intent?: IPaymentIntent | null; 274 | } 275 | /** Properties of an Owner. */ 276 | export interface IOwner { 277 | /** Owner address */ 278 | address?: string | null; 279 | 280 | /** Owner email */ 281 | email?: string | null; 282 | 283 | /** Owner name */ 284 | name?: string | null; 285 | 286 | /** Owner phone */ 287 | phone?: string | null; 288 | 289 | /** Owner verified_address */ 290 | verified_address?: string | null; 291 | 292 | /** Owner verified_email */ 293 | verified_email?: string | null; 294 | 295 | /** Owner verified_name */ 296 | verified_name?: string | null; 297 | 298 | /** Owner verified_phone */ 299 | verified_phone?: string | null; 300 | } 301 | /** Properties of a PaymentMethodDetails. */ 302 | export interface IPaymentMethodDetails { 303 | /** Payment Method type (e.g. "card_present") */ 304 | type?: string | null; 305 | 306 | /** PaymentMethodDetails card_present */ 307 | card_present?: ICardPresent | null; 308 | 309 | /** PaymentMethodDetails interac_present */ 310 | interac_present?: ICardPresent | null; 311 | 312 | /** PaymentMethodDetails wechat_pay */ 313 | wechat_pay?: IWechatPay | null; 314 | 315 | /** PaymentMethodDetails affirm */ 316 | affirm?: IAffirm | null; 317 | 318 | /** PaymentMethodDetails paynow */ 319 | paynow?: IPaynow | null; 320 | 321 | /** PaymentMethodDetails paypay */ 322 | paypay?: IPaypay | null; 323 | } 324 | /** Properties of a Refund. */ 325 | interface IRefund { 326 | /** Refund id */ 327 | id?: string | null; 328 | 329 | /** Refund amount */ 330 | amount?: number | null; 331 | 332 | /** Refund charge */ 333 | charge?: string | null; 334 | 335 | /** Time at which the Refund object was created. Measured in seconds since the Unix epoch */ 336 | created?: number | null; 337 | 338 | /** Three-letter ISO currency code, in lowercase. Must be a supported currency */ 339 | currency?: string | null; 340 | 341 | /** Meta data in JSON format */ 342 | metadata?: {[k: string]: string} | null; 343 | 344 | /** Reason for refund */ 345 | reason?: string | null; 346 | 347 | /** Status of refund */ 348 | status?: string | null; 349 | 350 | /** Actual details of the payment method */ 351 | payment_method_details?: IPaymentMethodDetails | null; 352 | 353 | /** If the refund failed, the reason for refund failure if known. */ 354 | failure_reason?: string | null; 355 | } 356 | /** Properties of a Refunds. */ 357 | interface IRefunds { 358 | /** Refunds data */ 359 | data?: IRefund[] | null; 360 | 361 | /** Refunds has_more */ 362 | has_more?: boolean | null; 363 | 364 | /** Refunds total_count */ 365 | total_count?: number | null; 366 | } 367 | /** Properties of a Charge. */ 368 | interface ICharge { 369 | /** ID for charge */ 370 | id?: string | null; 371 | 372 | /** Amount that is associated with the charge */ 373 | amount?: number | null; 374 | 375 | /** Amount that is associated with a refund of the charge */ 376 | amount_refunded?: number | null; 377 | 378 | /** Whether this charge has been captured */ 379 | captured?: boolean | null; 380 | 381 | /** Whether this charge has been refunded */ 382 | refunded?: boolean | null; 383 | 384 | /** Time at which the Charge object was created. Measured in seconds since the Unix epoch */ 385 | created?: number | null; 386 | 387 | /** Three-letter ISO currency code, in lowercase. Must be a supported currency. */ 388 | currency?: string | null; 389 | 390 | /** An arbitrary string attached to the object. Often useful for displaying to users. */ 391 | description?: string | null; 392 | 393 | /** An arbitrary string to be displayed on your customer's credit card statement. */ 394 | statement_descriptor?: string | null; 395 | 396 | /** Email address that the receipt for the resulting payment will be sent to. */ 397 | receipt_email?: string | null; 398 | 399 | /** Failure code if the charge was declined */ 400 | failure_code?: string | null; 401 | 402 | /** Message associated with the failure code */ 403 | failure_message?: string | null; 404 | 405 | /** Whether this charge was made in live mode or not */ 406 | livemode?: boolean | null; 407 | 408 | /** Meta data in JSON format */ 409 | metadata?: {[k: string]: string} | null; 410 | 411 | /** Source associated with the charge */ 412 | source?: ISource | null; 413 | 414 | /** Payment intent ID associated with the charge */ 415 | payment_intent?: string | null; 416 | 417 | /** Status of the charge */ 418 | status?: string | null; 419 | 420 | /** Payment method ID */ 421 | payment_method?: string | null; 422 | 423 | /** Actual details of the payment method */ 424 | payment_method_details?: IPaymentMethodDetails | null; 425 | 426 | /** Whether the charge was paid */ 427 | paid?: boolean | null; 428 | 429 | /** Receipt URL */ 430 | receipt_url?: string | null; 431 | 432 | /** Refunds associated with charge */ 433 | refunds?: IRefunds | null; 434 | } 435 | /** Properties of a Charges. */ 436 | interface ICharges { 437 | /** Charges data */ 438 | data?: ICharge[] | null; 439 | 440 | /** Charges has_more */ 441 | has_more?: boolean | null; 442 | 443 | /** Charges total_count */ 444 | total_count?: number | null; 445 | } 446 | /** Properties of a CardPresent. */ 447 | interface ICardPresent { 448 | /** The last four digits of the card. */ 449 | last4?: string | null; 450 | 451 | /** Card brand */ 452 | brand?: string | null; 453 | 454 | /** Customer's signature if signed */ 455 | evidence_customer_signature?: string | null; 456 | 457 | /** Method used by POS to read the card */ 458 | read_method?: string | null; 459 | 460 | /** The EMV authorization response payload */ 461 | emv_auth_data?: string | null; 462 | 463 | /** The EMV authorization response code */ 464 | authorization_response_code?: string | null; 465 | 466 | /** AID */ 467 | dedicated_file_name?: string | null; 468 | 469 | /** AID name */ 470 | application_preferred_name?: string | null; 471 | 472 | /** TVR */ 473 | terminal_verification_results?: string | null; 474 | 475 | /** TSI */ 476 | transaction_status_information?: string | null; 477 | 478 | /** CVM type */ 479 | cvm_type?: string | null; 480 | 481 | /** CardPresent reader */ 482 | reader?: string | null; 483 | 484 | /** CardPresent fingerprint */ 485 | fingerprint?: string | null; 486 | 487 | /** CardPresent authorization_code */ 488 | authorization_code?: string | null; 489 | 490 | /** CardPresent location */ 491 | location?: string | null; 492 | } 493 | 494 | interface IWechatPay { 495 | 496 | /** WechatPay reader */ 497 | reader?: string | null; 498 | 499 | /** WechatPay location */ 500 | location?: string | null; 501 | 502 | /** WeChat Pay transactionId */ 503 | transactionId?: string | null; 504 | } 505 | 506 | interface IAffirm { 507 | 508 | /** Affirm reader */ 509 | reader?: string | null; 510 | 511 | /** Affirm location */ 512 | location?: string | null; 513 | 514 | /** Affirm transactionId */ 515 | transactionId?: string | null; 516 | } 517 | 518 | interface IPaynow { 519 | 520 | /** Paynow reader */ 521 | reader?: string | null; 522 | 523 | /** Paynow location */ 524 | location?: string | null; 525 | 526 | /** Paynow reference */ 527 | reference?: string | null; 528 | } 529 | 530 | interface IPaypay { 531 | 532 | /** Paypay reader */ 533 | reader?: string | null; 534 | 535 | /** Paypay location */ 536 | location?: string | null; 537 | } 538 | 539 | /** Properties of a Source. */ 540 | export interface ISource { 541 | /** Unique identifier for the source card object. */ 542 | id?: string | null; 543 | 544 | /** Source type (e.g. "card_present") */ 545 | type?: string | null; 546 | 547 | /** Card payment method */ 548 | card_present?: ICardPresent | null; 549 | 550 | /** Interac version of card present */ 551 | interac_present?: ICardPresent | null; 552 | 553 | /** Meta data in JSON format */ 554 | metadata?: {[k: string]: string} | null; 555 | 556 | /** Owner data */ 557 | owner?: IOwner | null; 558 | } 559 | export interface IPaymentIntent { 560 | /** Unique identifier for the Payment Intent object */ 561 | id?: string | null; 562 | 563 | /** Time at which the Payment Intent object was created. Measured in seconds since the Unix epoch */ 564 | created?: number | null; 565 | 566 | /** Status of this PaymentIntent */ 567 | status?: string | null; 568 | 569 | /** Amount intended to be collected by this Payment Intent */ 570 | amount?: number | null; 571 | 572 | /** Three-letter ISO currency code, in lowercase. Must be a supported currency. */ 573 | currency?: string | null; 574 | 575 | /** Card present payment source field map */ 576 | source?: ISource | null; 577 | 578 | /** An arbitrary string to be displayed on your customer's credit card statement. */ 579 | statement_descriptor?: string | null; 580 | 581 | /** An arbitrary string attached to the object. Often useful for displaying to users. */ 582 | description?: string | null; 583 | 584 | /** Email address that the receipt for the resulting payment will be sent to. */ 585 | receipt_email?: string | null; 586 | 587 | /** Whether this charge was made in live mode or not */ 588 | livemode?: boolean | null; 589 | 590 | /** Last payment error on a charge (if retrieved) */ 591 | last_payment_error?: IErrorResponse | null; 592 | 593 | /** Meta data in JSON format */ 594 | metadata?: {[k: string]: string} | null; 595 | 596 | /** Charges associated with the payment intent */ 597 | charges?: ICharges | null; 598 | 599 | /** ID for payment method */ 600 | payment_method?: string | null; 601 | 602 | /** PaymentMethod types supported on the payment intent */ 603 | payment_method_types?: (string[]|null); 604 | } 605 | 606 | export interface ISetupIntent { 607 | /** Unique identifier for the object. */ 608 | id?: (string|null); 609 | 610 | /** The client secret of this SetupIntent. Used for client-side retrieval using a publishable key. */ 611 | client_secret?: (string|null); 612 | 613 | /** ID of the Customer this SetupIntent belongs to, if one exists. */ 614 | customer?: (string|null); 615 | 616 | /** An arbitrary string attached to the object. Often useful for displaying to users. */ 617 | description?: (string|null); 618 | 619 | /** The error encountered in the previous SetupIntent confirmation. */ 620 | last_setup_error?: ILastSetupError | null; 621 | 622 | /** Meta data in JSON format */ 623 | metadata?: ({ [k: string]: string }|null); 624 | 625 | /** If present, this property tells you what actions you need to take in order for your customer to continue payment setup. */ 626 | next_action?: INextAction | null; 627 | 628 | /** ID of the payment method used with this SetupIntent. */ 629 | payment_method?: (string|null); 630 | 631 | /** The list of payment method types (e.g. card) that this SetupIntent is allowed to set up. */ 632 | payment_method_types?: (string[]|null); 633 | 634 | /** Status of this SetupIntent, one of requires_payment_method, requires_confirmation, requires_action, processing, canceled, or succeeded. */ 635 | status?: (string|null); 636 | 637 | /** Indicates how the payment method is intended to be used in the future. */ 638 | usage?: (string|null); 639 | 640 | /** Time at which the object was created. Measured in seconds since the Unix epoch. */ 641 | created?: (number|null); 642 | 643 | /** The most recent SetupAttempt for this SetupIntent. */ 644 | latest_attempt?: (ISetupAttempt|null); 645 | 646 | /** Has the value true if the object exists in live mode or the value false if the object exists in test mode. */ 647 | livemode?: (boolean|null); 648 | 649 | /** ID of the multi use Mandate generated by the SetupIntent. */ 650 | mandate?: (string|null); 651 | 652 | /** ID of the single_use Mandate generated by the SetupIntent. */ 653 | single_use_mandate?: (string|null); 654 | 655 | /** ID of the Connect application that created the SetupIntent. */ 656 | application?: (string|null); 657 | 658 | /** The account (if any) for which the setup is intended. */ 659 | on_behalf_of?: (string|null); 660 | 661 | /** Payment-method-specific configuration for this SetupIntent. */ 662 | payment_method_options?: (IPaymentMethodOptions|null); 663 | } 664 | 665 | /** Properties of a SetupAttempt. */ 666 | export interface ISetupAttempt { 667 | 668 | /** Unique identifier for the object. */ 669 | id?: (string|null); 670 | 671 | /** String representing the object’s type: "setup_attempt" */ 672 | object?: (string|null); 673 | 674 | /** ID of the Connect application that created the SetupIntent. */ 675 | application?: (string|null); 676 | 677 | /** Time at which the object was created. Measured in seconds since the Unix epoch. */ 678 | created?: (number|null); 679 | 680 | /** ID of the Customer this SetupIntent belongs to, if one exists. */ 681 | customer?: (string|null); 682 | 683 | /** Has the value true if the object exists in live mode or the value false if the object exists in test mode. */ 684 | livemode?: (boolean|null); 685 | 686 | /** The account (if any) for which the setup is intended. */ 687 | on_behalf_of?: (string|null); 688 | 689 | /** ID of the payment method used with this SetupAttempt. */ 690 | payment_method?: (string|null); 691 | 692 | /** Details about the payment method at the time of SetupIntent confirmation. */ 693 | payment_method_details?: (IPaymentMethodDetails|null); 694 | 695 | /** The error encountered during this attempt to confirm the SetupIntent, if any. */ 696 | setup_error?: (ISetupError|null); 697 | 698 | /** ID of the SetupIntent that this attempt belongs to. */ 699 | setup_intent?: (string|null); 700 | 701 | /** Status of this SetupAttempt, one of requires_confirmation, requires_action, processing, succeeded, failed, or abandoned. */ 702 | status?: (string|null); 703 | 704 | /** The value of usage on the SetupIntent at the time of this confirmation, one of off_session or on_session. */ 705 | usage?: (string|null); 706 | } 707 | 708 | /** Properties of a SetupError. */ 709 | export interface ISetupError { 710 | 711 | /** For some errors that could be handled programmatically, a short string indicating the error code reported. */ 712 | code?: (string|null); 713 | 714 | /** For card errors resulting from a card issuer decline, a short string indicating the card issuer’s reason for the decline if they provide one. */ 715 | decline_code?: (string|null); 716 | 717 | /** A URL to more information about the error code reported. */ 718 | doc_url?: (string|null); 719 | 720 | /** A human-readable message providing more details about the error. For card errors, these messages can be shown to your users. */ 721 | message?: (string|null); 722 | 723 | /** If the error is parameter-specific, the parameter related to the error. For example, you can use this to display a message near the correct form field. */ 724 | param?: (string|null); 725 | 726 | /** The PaymentMethod object for errors returned on a request involving a PaymentMethod. */ 727 | payment_method?: (IPaymentMethod|null); 728 | 729 | /** If the error is specific to the type of payment method, the payment method type that had a problem. This field is only populated for invoice-related errors. */ 730 | payment_method_type?: (string|null); 731 | 732 | /** The type of error returned. One of api_connection_error, api_error, authentication_error, card_error, idempotency_error, invalid_request_error, or rate_limit_error */ 733 | type?: (string|null); 734 | } 735 | 736 | /** Properties of an ActivateTerminalRequest. */ 737 | export interface IActivateTerminalRequest { 738 | /** An activation token obtained from Stripe that can be used to activate the reader */ 739 | pos_activation_token?: string | null; 740 | 741 | /** The fingerprint for the POS authenticating to rabbit */ 742 | pos_device_id?: string | null; 743 | 744 | /** The terminal hardware information */ 745 | pos_hardware_info?: any | null; 746 | 747 | /** The terminal software information */ 748 | pos_software_info?: any | null; 749 | 750 | /** Provide RPC error if reader is currently in use */ 751 | fail_if_in_use?: boolean | null; 752 | 753 | /** The logical identity of terminal (i.e. lane number) authenticating to rabbit. */ 754 | terminal_id?: string | null; 755 | 756 | /** ActivateTerminalRequest terminal_ip */ 757 | terminal_ip?: string | null; 758 | 759 | /** The store name associated with the POS */ 760 | store_name?: string | null; 761 | 762 | /** The store address associated with the POS */ 763 | store_address?: any | null; 764 | } 765 | 766 | /** Properties of a SetReaderDisplayRequest. */ 767 | export interface ISetReaderDisplayRequest { 768 | /** SetReaderDisplayRequest type */ 769 | type?: string | null; 770 | 771 | /** SetReaderDisplayRequest cart */ 772 | cart?: ICart | null; 773 | } 774 | 775 | interface ICart { 776 | /** All line items in the basket */ 777 | line_items?: ILineItem[] | null; 778 | 779 | /** Modifiers that have been applied to the basket. */ 780 | modifiers?: IModifier[] | null; 781 | 782 | /** Any discounts that have been added to the basket. */ 783 | discounts?: IDiscount[] | null; 784 | 785 | /** Tenders that have been charged/refunded */ 786 | tenders?: ITender[] | null; 787 | 788 | /** Total amount of tax */ 789 | tax?: number | null; 790 | 791 | /** Total balance of cart due */ 792 | total?: number | null; 793 | 794 | /** The currency of the basket (i.e. USD or AUD). */ 795 | currency?: string | null; 796 | } 797 | 798 | /** Properties of a LineItem. */ 799 | interface ILineItem { 800 | /** LineItem quantity */ 801 | quantity?: number | null; 802 | 803 | /** A detailed description of the item. */ 804 | description?: string | null; 805 | 806 | /** This is equal to extended_price - discount + modifiers */ 807 | amount?: number | null; 808 | 809 | /** The discounts that have been applied to this line item. */ 810 | discounts?: IDiscount[] | null; 811 | 812 | /** The modifiers that have been applied to this line item. */ 813 | modifiers?: IModifier[] | null; 814 | } 815 | 816 | interface IModifier { 817 | /** A detailed description of discount. */ 818 | description?: string | null; 819 | 820 | /** Amount in cents of the modification. */ 821 | amount?: number | null; 822 | } 823 | /** Properties of a Discount. */ 824 | interface IDiscount { 825 | /** A detailed description of discount. */ 826 | description?: string | null; 827 | 828 | /** The amount and mechanism of the discount */ 829 | amount?: number | null; 830 | } 831 | /** Properties of a Tender. */ 832 | interface ITender { 833 | /** A detailed description of tender. */ 834 | description?: string | null; 835 | 836 | /** Amount in cents of the tender. */ 837 | amount?: number | null; 838 | } 839 | 840 | interface ILastSetupError { 841 | 842 | /** For some errors that could be handled programmatically, a short string indicating the error code reported. */ 843 | code?: (string|null); 844 | 845 | /** For card errors resulting from a card issuer decline, a short string indicating the card issuer’s reason for the decline if they provide one. */ 846 | decline_code?: (string|null); 847 | 848 | /** A URL to more information about the error code reported. */ 849 | doc_url?: (string|null); 850 | 851 | /** A human-readable message providing more details about the error. For card errors, these messages can be shown to users. */ 852 | message?: (string|null); 853 | 854 | /** If the error is parameter-specific, the parameter related to the error. For example, you can use this to display a message near the correct form field. */ 855 | param?: (string|null); 856 | 857 | /** The PaymentMethod object for errors returned on a request involving a PaymentMethod. */ 858 | payment_method?: (IPaymentMethod|null); 859 | 860 | /** One of: api_connection_error, api_error, authentication_error, card_error, idempotency_error, invalid_request_error, or rate_limit_error */ 861 | type?: (string|null); 862 | } 863 | 864 | interface INextAction { 865 | 866 | /** Contains instructions for authenticating by redirecting your customer to another page or application. */ 867 | redirect_to_url?: (IRedirectToUrl|null); 868 | 869 | /** Type of the next action to perform, one of redirect_to_url or use_stripe_sdk. */ 870 | type?: (string|null); 871 | 872 | /** When confirming a SetupIntent with Stripe.js, Stripe.js depends on the contents of this dictionary to invoke authentication flows. */ 873 | use_stripe_sdk?: ({ [k: string]: string }|null); 874 | } 875 | 876 | interface IRedirectToUrl { 877 | 878 | /** If the customer does not exit their browser while authenticating, they will be redirected to this specified URL after completion. */ 879 | return_url?: (string|null); 880 | 881 | /** The URL you must redirect your customer to in order to authenticate. */ 882 | url?: (string|null); 883 | } 884 | interface IPaymentMethodOptions { 885 | 886 | /** PaymentMethodOptions card */ 887 | card?: (ICardOptions|null); 888 | } 889 | 890 | interface ICardOptions { 891 | 892 | /** CardOptions request_three_d_secure */ 893 | request_three_d_secure?: (Request3dSecureType|null); 894 | } 895 | 896 | type Request3dSecureType = "automatic"| "any"; 897 | 898 | /** Method enum. */ 899 | type Method = 900 | "automatic"| "manual"; 901 | 902 | export type ITextToSpeechStatus = 'off' | 'headphones' | 'speakers'; 903 | 904 | export interface IAccessibilitySettings { 905 | textToSpeechStatus: ITextToSpeechStatus; 906 | } 907 | 908 | export interface IReaderSettings { 909 | accessibilitySettings: IAccessibilitySettings | IErrorResponse; 910 | } 911 | 912 | export interface IAccessibilityParameters { 913 | enableTextToSpeechSpeakers: boolean; 914 | } 915 | 916 | export interface ISetReaderSettingsRequest { 917 | accessibility_parameters?: null | IAccessibilityParameters; 918 | } 919 | --------------------------------------------------------------------------------