├── .npmignore ├── tests └── types │ ├── .eslintignore │ ├── .gitignore │ └── scripts │ ├── update-ts-snapshot.mjs │ ├── test.mjs │ └── ts-version-snapshot.json ├── lib ├── index.d.ts ├── index.d.mts ├── index.mjs └── index.js ├── pure ├── index.d.mts ├── index.d.ts ├── index.mjs └── index.js ├── .babelrc ├── .prettierignore ├── .eslintignore ├── .gitignore ├── types ├── stripe-js │ ├── confirmation-tokens.d.ts │ ├── ephemeral-keys.d.ts │ ├── orders.d.ts │ ├── elements │ │ ├── issuing │ │ │ ├── index.d.ts │ │ │ ├── issuing-card-cvc-display.d.ts │ │ │ ├── issuing-card-pin-display.d.ts │ │ │ ├── issuing-card-expiry-display.d.ts │ │ │ ├── issuing-card-copy-button.d.ts │ │ │ ├── issuing-card-number-display.d.ts │ │ │ └── issuing-add-to-wallet-button.d.ts │ │ ├── index.d.ts │ │ ├── payment-form.d.ts │ │ ├── currency-selector.d.ts │ │ ├── payment-method-messaging.d.ts │ │ ├── card-cvc.d.ts │ │ ├── card-expiry.d.ts │ │ ├── iban.d.ts │ │ ├── au-bank-account.d.ts │ │ ├── apple-pay.d.ts │ │ ├── link-authentication.d.ts │ │ ├── payment-request-button.d.ts │ │ ├── shipping-address.d.ts │ │ ├── card-number.d.ts │ │ ├── address.d.ts │ │ ├── card.d.ts │ │ ├── base.d.ts │ │ └── tax-id.d.ts │ ├── index.d.ts │ ├── hosted-checkout.d.ts │ ├── financial-connections.d.ts │ ├── token-and-sources.d.ts │ └── embedded-checkout.d.ts ├── .eslintrc.yml ├── utils.d.ts ├── pure.d.ts ├── api │ ├── verification-sessions.d.ts │ ├── index.d.ts │ ├── bank-accounts.d.ts │ ├── shared.d.ts │ ├── orders.d.ts │ ├── cards.d.ts │ ├── financial-connections.d.ts │ ├── confirmation-tokens.d.ts │ └── setup-intents.d.ts ├── shared.d.ts └── index.d.ts ├── .prettierrc.yml ├── src ├── testUtils.ts ├── index.ts ├── pure.ts ├── shared.test.ts ├── pure.test.ts ├── shared.ts └── index.test.ts ├── examples ├── parcel │ ├── .babelrc │ ├── src │ │ ├── index.html │ │ ├── styles.css │ │ └── index.js │ └── package.json └── rollup │ ├── .babelrc │ ├── server.js │ ├── public │ ├── index.html │ └── styles.css │ ├── rollup.config.js │ ├── package.json │ └── src │ └── index.js ├── scripts ├── is_release_candidate.js ├── copy-types └── publish ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ └── BUG.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── test.yml │ └── stale.yml ├── jest.config.js ├── tsconfig.json ├── .eslintrc.yml ├── rollup.config.js ├── LICENSE ├── CONTRIBUTING.md ├── package.json └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | examples -------------------------------------------------------------------------------- /tests/types/.eslintignore: -------------------------------------------------------------------------------- 1 | src 2 | -------------------------------------------------------------------------------- /lib/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from '../dist'; 2 | -------------------------------------------------------------------------------- /lib/index.d.mts: -------------------------------------------------------------------------------- 1 | export * from '../dist'; 2 | -------------------------------------------------------------------------------- /lib/index.mjs: -------------------------------------------------------------------------------- 1 | export * from '../dist/index.mjs'; 2 | -------------------------------------------------------------------------------- /pure/index.d.mts: -------------------------------------------------------------------------------- 1 | export * from '../dist/pure'; 2 | -------------------------------------------------------------------------------- /pure/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from '../dist/pure'; 2 | -------------------------------------------------------------------------------- /pure/index.mjs: -------------------------------------------------------------------------------- 1 | export * from '../dist/pure.mjs'; 2 | -------------------------------------------------------------------------------- /tests/types/.gitignore: -------------------------------------------------------------------------------- 1 | package.json 2 | yarn.lock 3 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"] 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | package.json 4 | pure -------------------------------------------------------------------------------- /pure/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../dist/pure'); 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | examples 4 | tests/types 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .cache 3 | node_modules 4 | dist 5 | *.log 6 | .vim 7 | .vscode/ -------------------------------------------------------------------------------- /types/stripe-js/confirmation-tokens.d.ts: -------------------------------------------------------------------------------- 1 | export {CreateConfirmationToken} from '../api'; 2 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef 2 | module.exports = require('../dist'); 3 | -------------------------------------------------------------------------------- /types/stripe-js/ephemeral-keys.d.ts: -------------------------------------------------------------------------------- 1 | export interface EphemeralKeyNonceOptions { 2 | issuingCard: string; 3 | } 4 | -------------------------------------------------------------------------------- /.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/testUtils.ts: -------------------------------------------------------------------------------- 1 | import {RELEASE_TRAIN} from './shared'; 2 | 3 | export const SCRIPT_SRC = `https://js.stripe.com/${RELEASE_TRAIN}/stripe.js`; 4 | -------------------------------------------------------------------------------- /types/utils.d.ts: -------------------------------------------------------------------------------- 1 | // Polyfill for TypeScript < 3.5 compatibility 2 | export type Omit = Pick>; 3 | -------------------------------------------------------------------------------- /types/pure.d.ts: -------------------------------------------------------------------------------- 1 | import {loadStripe as _loadStripe} from './shared'; 2 | 3 | export const loadStripe: typeof _loadStripe & { 4 | setLoadParameters: (params: {advancedFraudSignals: boolean}) => void; 5 | }; 6 | -------------------------------------------------------------------------------- /types/api/verification-sessions.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The VerificationSession object. 3 | */ 4 | export interface VerificationSession { 5 | /** 6 | * Unique identifier for the object. 7 | */ 8 | id: string; 9 | } 10 | -------------------------------------------------------------------------------- /examples/parcel/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"], 3 | "plugins": [ 4 | [ 5 | "@babel/plugin-transform-runtime", 6 | { 7 | "regenerator": true 8 | } 9 | ] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /examples/rollup/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"], 3 | "plugins": [ 4 | [ 5 | "@babel/plugin-transform-runtime", 6 | { 7 | "regenerator": true 8 | } 9 | ] 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /types/shared.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeConstructorOptions, Stripe} from './stripe-js'; 2 | 3 | export const loadStripe: ( 4 | publishableKey: string, 5 | options?: StripeConstructorOptions | undefined 6 | ) => Promise; 7 | -------------------------------------------------------------------------------- /scripts/is_release_candidate.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line @typescript-eslint/no-var-requires 2 | const {releaseCandidate} = require('../package.json'); 3 | 4 | // coerce boolean to 0 or 1 and default undefined to 0 5 | console.log(+!!releaseCandidate); 6 | -------------------------------------------------------------------------------- /examples/rollup/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const app = express(); 4 | const port = 3000; 5 | 6 | app.use(express.static('public')); 7 | app.use(express.static('dist')); 8 | 9 | app.listen(port, () => console.log(`Listening on port ${port}!`)); 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Stripe Support 4 | url: https://support.stripe.com/contact 5 | about: If you are having general trouble with Stripe.js or your Stripe integration, please reach out to Stripe Support instead. 6 | -------------------------------------------------------------------------------- /examples/parcel/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Stripe.js Module - Parcel 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /types/stripe-js/orders.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Parameters that will be passed on to the Stripe API to confirm payment for an Order's PaymentIntent. 3 | */ 4 | export interface ProcessOrderParams { 5 | /** 6 | * The url your customer will be directed to after they complete payment. 7 | */ 8 | return_url: string; 9 | } 10 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './issuing-add-to-wallet-button'; 2 | export * from './issuing-card-number-display'; 3 | export * from './issuing-card-cvc-display'; 4 | export * from './issuing-card-expiry-display'; 5 | export * from './issuing-card-pin-display'; 6 | export * from './issuing-card-copy-button'; 7 | -------------------------------------------------------------------------------- /examples/rollup/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Stripe.js Module - Rollup 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './api'; 2 | export * from './stripe-js'; 3 | 4 | import {StripeConstructor} from './stripe-js'; 5 | 6 | export {loadStripe} from './shared'; 7 | 8 | declare global { 9 | interface Window { 10 | // Stripe.js must be loaded directly from https://js.stripe.com/v3, which 11 | // places a `Stripe` object on the window 12 | Stripe?: StripeConstructor; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /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 | globals: { 11 | // Suppress noise about enabling `esModuleInterop` 12 | 'ts-jest': {diagnostics: {ignoreCodes: [151001]}}, 13 | _VERSION: true, 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Summary & motivation 2 | 3 | 4 | 5 | ### Testing & documentation 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /types/api/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './shared'; 2 | export * from './payment-methods'; 3 | export * from './confirmation-tokens'; 4 | export * from './payment-intents'; 5 | export * from './orders'; 6 | export * from './setup-intents'; 7 | export * from './sources'; 8 | export * from './tokens'; 9 | export * from './bank-accounts'; 10 | export * from './cards'; 11 | export * from './verification-sessions'; 12 | export * from './financial-connections'; 13 | -------------------------------------------------------------------------------- /types/stripe-js/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './hosted-checkout'; 2 | export * from './checkout'; 3 | export * from './embedded-checkout'; 4 | export * from './elements'; 5 | export * from './elements-group'; 6 | export * from './ephemeral-keys'; 7 | export * from './financial-connections'; 8 | export * from './orders'; 9 | export * from './payment-intents'; 10 | export * from './payment-request'; 11 | export * from './setup-intents'; 12 | export * from './token-and-sources'; 13 | export * from './stripe'; 14 | -------------------------------------------------------------------------------- /examples/rollup/rollup.config.js: -------------------------------------------------------------------------------- 1 | const babel = require('rollup-plugin-babel'); 2 | const commonjs = require('@rollup/plugin-commonjs'); 3 | const resolve = require('@rollup/plugin-node-resolve'); 4 | 5 | module.exports.default = [ 6 | { 7 | input: 'src/index.js', 8 | output: { 9 | dir: 'dist', 10 | format: 'esm', 11 | }, 12 | plugins: [ 13 | babel({runtimeHelpers: true}), 14 | resolve(), // so Rollup can find `ms` 15 | commonjs(), // so Rollup can convert `ms` to an ES module 16 | ], 17 | }, 18 | ]; 19 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | branches: [ master ] 5 | pull_request: 6 | branches: [ master ] 7 | jobs: 8 | test: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v2 12 | - uses: actions/setup-node@v1 13 | with: 14 | node-version: 20.x 15 | - run: yarn install --frozen-lockfile 16 | - run: yarn run lint 17 | - run: yarn run typecheck 18 | - run: yarn run test:unit 19 | - run: yarn run build && yarn run test:package-types 20 | - run: yarn run test:types 21 | -------------------------------------------------------------------------------- /types/stripe-js/hosted-checkout.d.ts: -------------------------------------------------------------------------------- 1 | export type CheckoutLocale = 2 | | 'auto' 3 | | 'bg' 4 | | 'cs' 5 | | 'da' 6 | | 'de' 7 | | 'el' 8 | | 'en' 9 | | 'en-GB' 10 | | 'es' 11 | | 'es-419' 12 | | 'et' 13 | | 'fi' 14 | | 'fil' 15 | | 'fr' 16 | | 'fr-CA' 17 | | 'hr' 18 | | 'hu' 19 | | 'id' 20 | | 'it' 21 | | 'ja' 22 | | 'lt' 23 | | 'lv' 24 | | 'ms' 25 | | 'mt' 26 | | 'nb' 27 | | 'nl' 28 | | 'pl' 29 | | 'pt' 30 | | 'pt-BR' 31 | | 'ro' 32 | | 'ru' 33 | | 'sk' 34 | | 'sl' 35 | | 'sv' 36 | | 'th' 37 | | 'tr' 38 | | 'zh' 39 | | 'zh-HK' 40 | | 'zh-TW'; 41 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /types/stripe-js/elements/index.d.ts: -------------------------------------------------------------------------------- 1 | export * from './address'; 2 | export * from './payment-form'; 3 | export * from './payment-method-messaging'; 4 | export * from './au-bank-account'; 5 | export * from './base'; 6 | export * from './card-cvc'; 7 | export * from './card-expiry'; 8 | export * from './card-number'; 9 | export * from './card'; 10 | export * from './currency-selector'; 11 | export * from './express-checkout'; 12 | export * from './iban'; 13 | export * from './link-authentication'; 14 | export * from './payment-request-button'; 15 | export * from './payment'; 16 | export * from './shipping-address'; 17 | export * from './issuing'; 18 | export * from './tax-id'; 19 | export * from './payment-form'; 20 | -------------------------------------------------------------------------------- /types/stripe-js/financial-connections.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Data to be sent with a `stripe.collectFinancialConnectionsAccounts` request. 3 | */ 4 | export interface CollectFinancialConnectionsAccountsOptions { 5 | /** 6 | * The client secret of the [Financial Connections Session](https://stripe.com/docs/api/financial_connections/session). 7 | */ 8 | clientSecret: string; 9 | } 10 | 11 | /** 12 | * Data to be sent with a `stripe.collectBankAccountToken` request. 13 | */ 14 | export interface CollectBankAccountTokenOptions { 15 | /** 16 | * The client secret of the [Financial Connections Session](https://stripe.com/docs/api/financial_connections/session). 17 | */ 18 | clientSecret: string; 19 | } 20 | -------------------------------------------------------------------------------- /scripts/copy-types: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Sets the source and destination directories 4 | SRC_DIR="./types" 5 | DEST_DIR="./dist" 6 | 7 | # Finds all .d.ts files in the source directory and copies them 8 | find "$SRC_DIR" -type f -name '*.d.ts' | while read -r src_file; do 9 | # Constructs the destination file path 10 | dest_file="${src_file/$SRC_DIR/$DEST_DIR}" 11 | dest_file_mts="${dest_file/%.d.ts/.d.mts}" 12 | 13 | # Creates the destination directory if it doesn't exist 14 | mkdir -p "$(dirname "$dest_file")" 15 | 16 | # Copys the .d.ts file to the destination directory 17 | cp "$src_file" "$dest_file" 18 | cp "$src_file" "$dest_file_mts" 19 | done 20 | 21 | echo "All .d.ts files have been copied from $SRC_DIR to $DEST_DIR." -------------------------------------------------------------------------------- /examples/parcel/src/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | #root { 11 | text-align: center; 12 | max-width: 400px; 13 | margin: 40px auto; 14 | } 15 | 16 | .StripeElement { 17 | padding: 12px; 18 | border: 1px solid #ddd; 19 | margin-bottom: 8px; 20 | } 21 | 22 | button { 23 | background-color: royalblue; 24 | color: white; 25 | border-radius: 4px; 26 | font-size: 14px; 27 | font-weight: 500; 28 | border: 0; 29 | box-shadow: none; 30 | padding: 8px 24px; 31 | } 32 | -------------------------------------------------------------------------------- /examples/parcel/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parcel", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "parcel src/index.html" 7 | }, 8 | "browserslist": { 9 | "production": [ 10 | ">0.2%", 11 | "not dead", 12 | "not op_mini all" 13 | ], 14 | "development": [ 15 | "last 1 chrome version", 16 | "last 1 firefox version", 17 | "last 1 safari version" 18 | ] 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.7.7", 22 | "@babel/plugin-transform-runtime": "^7.7.6", 23 | "@babel/preset-env": "^7.7.7", 24 | "@babel/runtime": "^7.7.7", 25 | "parcel-bundler": "^1.12.4" 26 | }, 27 | "dependencies": { 28 | "@stripe/stripe-js": "^1.8.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/rollup/public/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | #root { 11 | text-align: center; 12 | max-width: 400px; 13 | margin: 40px auto; 14 | } 15 | 16 | .StripeElement { 17 | padding: 12px; 18 | border: 1px solid #ddd; 19 | margin-bottom: 8px; 20 | } 21 | 22 | button { 23 | background-color: royalblue; 24 | color: white; 25 | border-radius: 4px; 26 | font-size: 14px; 27 | font-weight: 500; 28 | border: 0; 29 | box-shadow: none; 30 | padding: 8px 24px; 31 | } 32 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | root: true 3 | extends: 4 | - eslint:recommended 5 | - plugin:@typescript-eslint/eslint-recommended 6 | - plugin:@typescript-eslint/recommended 7 | parser: '@typescript-eslint/parser' 8 | plugins: 9 | - jest 10 | - '@typescript-eslint' 11 | env: 12 | jest/globals: true 13 | browser: true 14 | rules: 15 | no-console: 0 16 | func-style: 2 17 | prefer-spread: 0 18 | consistent-return: 2 19 | prefer-arrow-callback: 20 | - 2 21 | - allowNamedFunctions: false 22 | allowUnboundThis: false 23 | no-unused-vars: 0 24 | jest/no-disabled-tests: 2 25 | jest/no-focused-tests: 2 26 | '@typescript-eslint/no-explicit-any': 0 27 | '@typescript-eslint/no-empty-interface': 0 28 | '@typescript-eslint/triple-slash-reference': 0 29 | '@typescript-eslint/no-unused-vars': 30 | - 2 31 | - ignoreRestSiblings: true 32 | -------------------------------------------------------------------------------- /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: 'dist/index.js', format: 'cjs'}, 24 | {file: 'dist/index.mjs', format: 'es'}, 25 | ], 26 | plugins: PLUGINS, 27 | }, 28 | { 29 | input: 'src/pure.ts', 30 | output: [ 31 | {file: 'dist/pure.js', format: 'cjs'}, 32 | {file: 'dist/pure.mjs', format: 'es'}, 33 | ], 34 | plugins: PLUGINS, 35 | }, 36 | ]; 37 | -------------------------------------------------------------------------------- /examples/rollup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rollup", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "rimraf dist && rollup -c && node server" 7 | }, 8 | "browserslist": { 9 | "production": [ 10 | ">0.2%", 11 | "not dead", 12 | "not op_mini all" 13 | ], 14 | "development": [ 15 | "last 1 chrome version", 16 | "last 1 firefox version", 17 | "last 1 safari version" 18 | ] 19 | }, 20 | "dependencies": { 21 | "@stripe/stripe-js": "^1.8.0", 22 | "express": "^4.20.0" 23 | }, 24 | "devDependencies": { 25 | "@babel/core": "^7.7.7", 26 | "@babel/plugin-transform-runtime": "^7.7.6", 27 | "@babel/preset-env": "^7.7.7", 28 | "@babel/runtime": "^7.7.7", 29 | "@rollup/plugin-commonjs": "^11.0.0", 30 | "@rollup/plugin-node-resolve": "^6.0.0", 31 | "rimraf": "^3.0.0", 32 | "rollup": "^1.27.14", 33 | "rollup-plugin-babel": "^4.3.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /examples/rollup/src/index.js: -------------------------------------------------------------------------------- 1 | import {loadStripe} from '@stripe/stripe-js'; 2 | 3 | (async () => { 4 | // setup DOM 5 | const rootNode = document.getElementById('root'); 6 | const form = document.createElement('form'); 7 | const cardWrapper = document.createElement('div'); 8 | const button = document.createElement('button'); 9 | button.innerText = 'Pay'; 10 | form.appendChild(cardWrapper); 11 | form.appendChild(button); 12 | rootNode.appendChild(form); 13 | 14 | // setup Stripe.js and Elements 15 | const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); 16 | const elements = stripe.elements(); 17 | 18 | // setup card Element 19 | const cardElement = elements.create('card', {}); 20 | cardElement.mount(cardWrapper); 21 | 22 | // handle form submit 23 | form.addEventListener('submit', async (e) => { 24 | e.preventDefault(); 25 | const payload = await stripe.createPaymentMethod({ 26 | type: 'card', 27 | card: cardElement, 28 | }); 29 | console.log('[PaymentMethod]', payload); 30 | }); 31 | })(); 32 | -------------------------------------------------------------------------------- /examples/parcel/src/index.js: -------------------------------------------------------------------------------- 1 | import {loadStripe} from '@stripe/stripe-js'; 2 | 3 | import './styles.css'; 4 | 5 | (async () => { 6 | // setup DOM 7 | const rootNode = document.getElementById('root'); 8 | const form = document.createElement('form'); 9 | const cardWrapper = document.createElement('div'); 10 | const button = document.createElement('button'); 11 | button.innerText = 'Pay'; 12 | form.appendChild(cardWrapper); 13 | form.appendChild(button); 14 | rootNode.appendChild(form); 15 | 16 | // setup Stripe.js and Elements 17 | const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); 18 | const elements = stripe.elements(); 19 | 20 | // setup card Element 21 | const cardElement = elements.create('card', {}); 22 | cardElement.mount(cardWrapper); 23 | 24 | // handle form submit 25 | form.addEventListener('submit', async (e) => { 26 | e.preventDefault(); 27 | const payload = await stripe.createPaymentMethod({ 28 | type: 'card', 29 | card: cardElement, 30 | }); 31 | console.log('[PaymentMethod]', payload); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 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 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import {StripeConstructor} from '../types'; 2 | import {loadScript, initStripe, LoadStripe} from './shared'; 3 | 4 | let stripePromise: Promise | null; 5 | let loadCalled = false; 6 | 7 | const getStripePromise: () => Promise = () => { 8 | if (stripePromise) { 9 | return stripePromise; 10 | } 11 | 12 | stripePromise = loadScript(null).catch((error) => { 13 | // clear cache on error 14 | stripePromise = null; 15 | return Promise.reject(error); 16 | }); 17 | return stripePromise; 18 | }; 19 | 20 | // Execute our own script injection after a tick to give users time to do their 21 | // own script injection. 22 | Promise.resolve() 23 | .then(() => getStripePromise()) 24 | .catch((error) => { 25 | if (!loadCalled) { 26 | console.warn(error); 27 | } 28 | }); 29 | 30 | export const loadStripe: LoadStripe = (...args) => { 31 | loadCalled = true; 32 | const startTime = Date.now(); 33 | 34 | // if previous attempts are unsuccessful, will re-load script 35 | return getStripePromise().then((maybeStripe) => 36 | initStripe(maybeStripe, args, startTime) 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale issues and PRs' 2 | on: 3 | schedule: 4 | - cron: '30 1 * * *' # Run daily at 1:30 AM UTC 5 | 6 | jobs: 7 | stale: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | issues: write 11 | pull-requests: write 12 | steps: 13 | - uses: actions/stale@v9 14 | with: 15 | # Number of days of inactivity before an issue becomes stale 16 | days-before-stale: 20 17 | # Number of days of inactivity before a stale issue is closed 18 | days-before-close: 7 19 | # Never mark PRs as stale or close them 20 | days-before-pr-stale: -1 21 | days-before-pr-close: -1 22 | # Issues with these labels will never be considered stale 23 | exempt-issue-labels: 'pinned,security' 24 | # Comment to post when marking an issue as stale 25 | stale-issue-message: > 26 | This issue has been automatically marked as stale because it has not had 27 | recent activity. It will be closed if no further activity occurs. Thank you 28 | for your contributions. 29 | # Close comment is disabled 30 | # close-issue-message and close-pr-message are omitted to disable close comments -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-card-cvc-display.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementStyle} from '../base'; 2 | 3 | export type StripeIssuingCardCvcDisplayElement = StripeElementBase & { 4 | /** 5 | * Updates the options the `IssuingCardCvcDisplayElement` was initialized with. 6 | * Updates are merged into the existing configuration. 7 | * 8 | * The styles of an `IssuingCardCvcDisplayElement` can be dynamically changed using `element.update`. 9 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 10 | */ 11 | update(options: Partial): void; 12 | }; 13 | 14 | export interface StripeIssuingCardCvcDisplayElementOptions { 15 | /** 16 | * The token (e.g. `ic_abc123`) of the issued card to display in this Element 17 | */ 18 | issuingCard: string; 19 | 20 | /** 21 | * The secret component of the ephemeral key with which to authenticate this sensitive 22 | * card details request 23 | */ 24 | ephemeralKeySecret?: string; 25 | 26 | /** 27 | * The nonce used to mint the ephemeral key provided in `ephemeralKeySecret` 28 | */ 29 | nonce?: string; 30 | 31 | style?: StripeElementStyle; 32 | } 33 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-card-pin-display.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementStyle} from '../base'; 2 | 3 | export type StripeIssuingCardPinDisplayElement = StripeElementBase & { 4 | /** 5 | * Updates the options the `IssuingCardPinDisplayElement` was initialized with. 6 | * Updates are merged into the existing configuration. 7 | * 8 | * The styles of an `IssuingCardPinDisplayElement` can be dynamically changed using `element.update`. 9 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 10 | */ 11 | update(options: Partial): void; 12 | }; 13 | 14 | export interface StripeIssuingCardPinDisplayElementOptions { 15 | /** 16 | * The token (e.g. `ic_abc123`) of the issued card to display in this Element 17 | */ 18 | issuingCard: string; 19 | 20 | /** 21 | * The secret component of the ephemeral key with which to authenticate this sensitive 22 | * card details request 23 | */ 24 | ephemeralKeySecret?: string; 25 | 26 | /** 27 | * The nonce used to mint the ephemeral key provided in `ephemeralKeySecret` 28 | */ 29 | nonce?: string; 30 | 31 | style?: StripeElementStyle; 32 | } 33 | -------------------------------------------------------------------------------- /types/stripe-js/elements/payment-form.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeError} from '../stripe'; 2 | import {StripeElementBase} from './base'; 3 | 4 | export type StripePaymentFormElement = StripeElementBase & { 5 | /** 6 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 7 | */ 8 | on( 9 | eventType: 'ready', 10 | handler: (event: {elementType: 'paymentForm'}) => any 11 | ): StripePaymentFormElement; 12 | once( 13 | eventType: 'ready', 14 | handler: (event: {elementType: 'paymentForm'}) => any 15 | ): StripePaymentFormElement; 16 | off( 17 | eventType: 'ready', 18 | handler?: (event: {elementType: 'paymentForm'}) => any 19 | ): StripePaymentFormElement; 20 | 21 | /** 22 | * Triggered when the element fails to load. 23 | */ 24 | on( 25 | eventType: 'loaderror', 26 | handler: (event: {elementType: 'paymentForm'; error: StripeError}) => any 27 | ): StripePaymentFormElement; 28 | once( 29 | eventType: 'loaderror', 30 | handler: (event: {elementType: 'paymentForm'; error: StripeError}) => any 31 | ): StripePaymentFormElement; 32 | off( 33 | eventType: 'loaderror', 34 | handler?: (event: {elementType: 'paymentForm'; error: StripeError}) => any 35 | ): StripePaymentFormElement; 36 | }; 37 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-card-expiry-display.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementStyle} from '../base'; 2 | 3 | export type StripeIssuingCardExpiryDisplayElement = StripeElementBase & { 4 | /** 5 | * Updates the options the `IssuingCardExpiryDisplayElement` was initialized with. 6 | * Updates are merged into the existing configuration. 7 | * 8 | * The styles of an `IssuingCardExpiryDisplayElement` can be dynamically changed using `element.update`. 9 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 10 | */ 11 | update(options: Partial): void; 12 | }; 13 | 14 | export interface StripeIssuingCardExpiryDisplayElementOptions { 15 | /** 16 | * The token (e.g. `ic_abc123`) of the issued card to display in this Element 17 | */ 18 | issuingCard: string; 19 | 20 | /** 21 | * The secret component of the ephemeral key with which to authenticate this sensitive 22 | * card details request 23 | */ 24 | ephemeralKeySecret?: string; 25 | 26 | /** 27 | * The nonce used to mint the ephemeral key provided in `ephemeralKeySecret` 28 | */ 29 | nonce?: string; 30 | 31 | style?: StripeElementStyle; 32 | } 33 | -------------------------------------------------------------------------------- /src/pure.ts: -------------------------------------------------------------------------------- 1 | import { 2 | validateLoadParams, 3 | loadScript, 4 | initStripe, 5 | LoadStripe, 6 | LoadParams, 7 | } from './shared'; 8 | 9 | type SetLoadParams = (params: LoadParams) => void; 10 | 11 | let loadParams: null | LoadParams; 12 | let loadStripeCalled = false; 13 | 14 | export const loadStripe: LoadStripe & {setLoadParameters: SetLoadParams} = ( 15 | ...args 16 | ) => { 17 | loadStripeCalled = true; 18 | const startTime = Date.now(); 19 | 20 | return loadScript(loadParams).then((maybeStripe) => 21 | initStripe(maybeStripe, args, startTime) 22 | ); 23 | }; 24 | 25 | loadStripe.setLoadParameters = (params): void => { 26 | // we won't throw an error if setLoadParameters is called with the same values as before 27 | if (loadStripeCalled && loadParams) { 28 | const validatedParams = validateLoadParams(params); 29 | const parameterKeys = Object.keys(validatedParams) as Array< 30 | keyof LoadParams 31 | >; 32 | 33 | const sameParameters = parameterKeys.reduce( 34 | (previousValue, currentValue) => { 35 | return ( 36 | previousValue && params[currentValue] === loadParams?.[currentValue] 37 | ); 38 | }, 39 | true 40 | ); 41 | 42 | if (sameParameters) { 43 | return; 44 | } 45 | } 46 | 47 | if (loadStripeCalled) { 48 | throw new Error( 49 | 'You cannot change load parameters after calling loadStripe' 50 | ); 51 | } 52 | 53 | loadParams = validateLoadParams(params); 54 | }; 55 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-card-copy-button.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementStyle} from '../base'; 2 | 3 | export type StripeIssuingCardCopyButtonElement = StripeElementBase & { 4 | /** 5 | * Triggered when the element is clicked. 6 | */ 7 | on( 8 | eventType: 'click', 9 | handler: (event: {elementType: 'issuingCardCopyButton'}) => any 10 | ): StripeIssuingCardCopyButtonElement; 11 | once( 12 | eventType: 'click', 13 | handler: (event: {elementType: 'issuingCardCopyButton'}) => any 14 | ): StripeIssuingCardCopyButtonElement; 15 | off( 16 | eventType: 'click', 17 | handler?: (event: {elementType: 'issuingCardCopyButton'}) => any 18 | ): StripeIssuingCardCopyButtonElement; 19 | 20 | /** 21 | * Updates the options the `IssuingCardCopyButtonElement` was initialized with. 22 | * Updates are merged into the existing configuration. 23 | * 24 | * The styles of an `IssuingCardCopyButtonElement` can be dynamically changed using `element.update`. 25 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 26 | */ 27 | update(options: Partial): void; 28 | }; 29 | 30 | export interface StripeIssuingCardCopyButtonElementOptions { 31 | /** 32 | * The issued card data element to copy to the user's clipboard 33 | */ 34 | toCopy: 'expiry' | 'cvc' | 'number' | 'pin'; 35 | 36 | style?: StripeElementStyle; 37 | } 38 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-card-number-display.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementStyle} from '../base'; 2 | 3 | export type StripeIssuingCardNumberDisplayElement = StripeElementBase & { 4 | /** 5 | * Updates the options the `IssuingCardNumberDisplayElement` was initialized with. 6 | * Updates are merged into the existing configuration. 7 | * 8 | * The styles of an `IssuingCardNumberDisplayElement` can be dynamically changed using `element.update`. 9 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 10 | */ 11 | update(options: Partial): void; 12 | 13 | /** 14 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 15 | */ 16 | on( 17 | eventType: 'ready', 18 | handler: (event: {elementType: 'issuingCardNumberDisplay'}) => any 19 | ): StripeIssuingCardNumberDisplayElement; 20 | }; 21 | 22 | export interface StripeIssuingCardNumberDisplayElementOptions { 23 | /** 24 | * The token (e.g. `ic_abc123`) of the issued card to display in this Element 25 | */ 26 | issuingCard: string; 27 | 28 | /** 29 | * The secret component of the ephemeral key with which to authenticate this sensitive 30 | * card details request 31 | */ 32 | ephemeralKeySecret?: string; 33 | 34 | /** 35 | * The nonce used to mint the ephemeral key provided in `ephemeralKeySecret` 36 | */ 37 | nonce?: string; 38 | 39 | style?: StripeElementStyle; 40 | } 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG.yml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report relating to the @stripe/stripe-js loading wrapper. 3 | title: "[BUG]: " 4 | labels: ["bug"] 5 | body: 6 | - type: markdown 7 | attributes: 8 | value: | 9 | Thanks for taking the time to fill out this bug report! This project is a very thin loading wrapper around Stripe.js. Please only file issues here that you believe represent bugs with the loader, not Stripe.js itself. 10 | 11 | If you're having general trouble with Stripe.js or your Stripe integration, please reach out to us using the form at https://support.stripe.com/email or come chat with us on the [Stripe Discord server](https://discord.com/invite/stripe). We're very proud of our level of service, and we're more than happy to help you out with your integration. 12 | - type: textarea 13 | id: what-happened 14 | attributes: 15 | label: What happened? 16 | description: Please include what you were trying to accomplish, and what happened instead. 17 | validations: 18 | required: true 19 | - type: input 20 | id: env 21 | attributes: 22 | label: Environment 23 | description: What browser and operating system are you seeing this issue on? What versions? 24 | placeholder: Chrome 99.0.4844.51 on macOS 12.2.1 25 | - type: input 26 | id: repro 27 | attributes: 28 | label: Reproduction 29 | description: Please include a link to a runnable reproduction, if you can. This will greatly increase the likelihood we are able to help. A Glitch or CodeSandbox link is perfect. 30 | placeholder: https://glitch.com/edit/#!/your-project 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Stripe.js 2 | 3 | Thanks for contributing to Stripe.js! 4 | 5 | ## Issues 6 | 7 | This project is a very thin loading wrapper around Stripe.js. Please only file 8 | issues here that you believe represent bugs with the loader, not Stripe.js 9 | itself. 10 | 11 | If you're having general trouble with Stripe.js or your Stripe integration, 12 | please reach out to us using the form at or 13 | come chat with us on the [Stripe Discord server][developer-chat]. We're very 14 | proud of our level of service, and we're more than happy to help you out with 15 | your integration. 16 | 17 | If you've found a bug in Stripe.js loading wrapper, please [let us know][issue]! 18 | 19 | ## Code review 20 | 21 | All pull requests will be reviewed by someone from Stripe before merging. At 22 | Stripe, we believe that code review is for explaining and having a discussion 23 | around code. For those new to code review, we strongly recommend [this 24 | video][code-review] on "code review culture." 25 | 26 | ## Developing 27 | 28 | Install dependencies: 29 | 30 | ```sh 31 | yarn install 32 | ``` 33 | 34 | We use a number of automated checks: 35 | 36 | - Jest, for testing 37 | - `yarn test` 38 | - ESLint, for assorted warnings 39 | - `yarn run lint` 40 | - Prettier, for code formatting 41 | - `yarn run prettier` 42 | 43 | You might want to configure your editor to automatically run these checks. Not 44 | passing any of these checks will cause the CI build to fail. 45 | 46 | [code-review]: https://www.youtube.com/watch?v=PJjmw9TRB7s 47 | [issue]: https://github.com/stripe/stripe-js/issues/new/choose 48 | [developer-chat]: https://stripe.com/go/developer-chat 49 | -------------------------------------------------------------------------------- /tests/types/scripts/update-ts-snapshot.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zx 2 | 3 | import 'zx/globals'; 4 | import fs from 'fs'; 5 | import path from 'path'; 6 | 7 | const allVersions = JSON.parse(await $`yarn info typescript versions --json`) 8 | .data; 9 | const timestamps = JSON.parse(await $`yarn info typescript time --json`).data; 10 | const nodeTypesTags = JSON.parse( 11 | await $`yarn info @types/node dist-tags --json` 12 | ).data; 13 | 14 | const threeYearsAgo = Date.now() - 3 * 365 * 24 * 60 * 60 * 1000; 15 | 16 | const selectedVersions = allVersions 17 | .filter((el) => el.match(/^\d+\.\d+\.\d+$/)) 18 | .reverse() 19 | .filter((version) => { 20 | const releaseDate = new Date(timestamps[version]).getTime(); 21 | return releaseDate > threeYearsAgo; 22 | }) 23 | .map((tsVersion) => { 24 | const parseVersion = (version) => { 25 | const [major, minor, patch] = version.split('.'); 26 | return { 27 | major: parseInt(major, 10), 28 | minor: parseInt(minor, 10), 29 | patch: parseInt(patch, 10), 30 | }; 31 | }; 32 | 33 | const typescript = parseVersion(tsVersion); 34 | 35 | const nodeTypesTag = `ts${typescript.major}.${typescript.minor}`; 36 | const nodeTypes = parseVersion(nodeTypesTags[nodeTypesTag]); 37 | 38 | return { 39 | typescript, 40 | nodeTypes, 41 | }; 42 | }) 43 | .reduce((acc, release) => { 44 | const {typescript} = release; 45 | const key = `${typescript.major}.${typescript.minor}`; 46 | if (!acc.has(key) || acc.get(key).patch < typescript.patch) { 47 | acc.set(key, release); 48 | } 49 | return acc; 50 | }, new Map()) 51 | .values(); 52 | 53 | fs.writeFileSync( 54 | path.join(__dirname, 'ts-version-snapshot.json'), 55 | JSON.stringify(Array.from(selectedVersions), null, 2) 56 | ); 57 | -------------------------------------------------------------------------------- /tests/types/scripts/test.mjs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env zx 2 | 3 | import fs from 'fs'; 4 | import {spawn} from 'child_process'; 5 | import path from 'path'; 6 | import 'zx/globals'; 7 | 8 | const versionSnapshot = JSON.parse( 9 | fs.readFileSync(path.join(__dirname, 'ts-version-snapshot.json'), 'utf8') 10 | ); 11 | 12 | const TYPE_TESTS_DIR = `${__dirname}/..`; 13 | 14 | // Ensure working directory is test directory 15 | cd(TYPE_TESTS_DIR); 16 | 17 | if (fs.existsSync(`${TYPE_TESTS_DIR}/package.json`)) { 18 | await $`rm package.json`; 19 | } 20 | 21 | await $`yarn init -sy`; 22 | 23 | function runTsc(filename, flags) { 24 | const tscArgs = [...flags, filename]; 25 | const proc = spawn('yarn', ['run', 'tsc', ...tscArgs], {stdio: 'inherit'}); 26 | 27 | return new Promise((resolve, reject) => { 28 | proc.on('error', (err) => { 29 | reject(err); 30 | }); 31 | 32 | proc.on('close', (code) => 33 | code === 0 ? resolve() : reject(new Error('tsc failed')) 34 | ); 35 | }); 36 | } 37 | 38 | const serializeVersion = ({major, minor, patch}) => 39 | [major, minor, patch].join('.'); 40 | 41 | let isFailure = false; 42 | for (const {typescript, nodeTypes} of versionSnapshot) { 43 | // Temporary fix for TS 5.2 as https://github.com/DefinitelyTyped/DefinitelyTyped/pull/73924/files 44 | // actually breaks with TS 5.2 and their npm is marking it as the tag for ts5.2. 45 | // pin to latest working version of @types/node for TS 5.2. 46 | const patchedNodeTypes = 47 | typescript.major === 5 && typescript.minor >= 2 && typescript.minor <= 5 48 | ? '24.10.3' 49 | : serializeVersion(nodeTypes); 50 | 51 | const typescriptVersion = `typescript@${serializeVersion(typescript)}`; 52 | const nodeTypesVersion = `@types/node@${patchedNodeTypes}`; 53 | 54 | console.log(`--- Testing with ${typescriptVersion} and ${nodeTypesVersion}`); 55 | 56 | await $`yarn add -s --no-progress ${typescriptVersion}`; 57 | await $`yarn add -s --no-progress ${nodeTypesVersion}`; 58 | 59 | let flags = ['--strict', '--noEmit']; 60 | 61 | try { 62 | await runTsc('src/valid.ts', flags); 63 | await runTsc('src/invalid.ts', flags); 64 | } catch (e) { 65 | console.error(e); 66 | isFailure = true; 67 | } 68 | } 69 | 70 | if (isFailure) process.exit(1); 71 | -------------------------------------------------------------------------------- /types/stripe-js/elements/issuing/issuing-add-to-wallet-button.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase} from '../base'; 2 | 3 | export type StripeIssuingAddToWalletButtonElement = StripeElementBase & { 4 | /** 5 | * Triggered when the element is clicked. 6 | */ 7 | on( 8 | eventType: 'click', 9 | handler: (event: {elementType: 'issuingAddToWalletButton'}) => any 10 | ): StripeIssuingAddToWalletButtonElement; 11 | once( 12 | eventType: 'click', 13 | handler: (event: {elementType: 'issuingAddToWalletButton'}) => any 14 | ): StripeIssuingAddToWalletButtonElement; 15 | off( 16 | eventType: 'click', 17 | handler?: (event: {elementType: 'issuingAddToWalletButton'}) => any 18 | ): StripeIssuingAddToWalletButtonElement; 19 | 20 | /** 21 | * Triggered when add to wallet flow is complete. 22 | */ 23 | on( 24 | eventType: 'success', 25 | handler: (event: {elementType: 'issuingAddToWalletButton'}) => any 26 | ): StripeIssuingAddToWalletButtonElement; 27 | once( 28 | eventType: 'success', 29 | handler: (event: {elementType: 'issuingAddToWalletButton'}) => any 30 | ): StripeIssuingAddToWalletButtonElement; 31 | off( 32 | eventType: 'success', 33 | handler?: (event: {elementType: 'issuingAddToWalletButton'}) => any 34 | ): StripeIssuingAddToWalletButtonElement; 35 | 36 | /** 37 | * Updates the options the `IssuingAddToWalletButtonElement` was initialized with. 38 | * Updates are merged into the existing configuration. 39 | */ 40 | update(options: Partial): void; 41 | }; 42 | 43 | export interface StripeIssuingAddToWalletButtonElementOptions { 44 | /** 45 | * The token (e.g. `ic_abc123`) of the issued card to add to the user's wallet. 46 | */ 47 | issuingCard: string; 48 | 49 | /** 50 | * The secret component of the ephemeral key with which to authenticate this sensitive 51 | * card provisioning request 52 | */ 53 | ephemeralKeySecret: string; 54 | 55 | /** 56 | * The nonce used to mint the ephemeral key provided in `ephemeralKeySecret` 57 | */ 58 | nonce: string; 59 | 60 | /** 61 | * The type of Add to Wallet button to display. For now, only 'apple' is supported. 62 | */ 63 | wallet: 'apple'; 64 | 65 | /** 66 | * The height of the button in pixels. Defaults to 44px. 67 | * Must be between 36px and 55px. 68 | */ 69 | buttonHeight?: number; 70 | } 71 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stripe/stripe-js", 3 | "version": "8.6.0", 4 | "description": "Stripe.js loading utility", 5 | "repository": "github:stripe/stripe-js", 6 | "main": "lib/index.js", 7 | "module": "lib/index.mjs", 8 | "jsnext:main": "lib/index.mjs", 9 | "types": "lib/index.d.ts", 10 | "typings": "lib/index.d.ts", 11 | "releaseCandidate": false, 12 | "scripts": { 13 | "test": "yarn lint && yarn test:unit && yarn test:package-types && yarn test:types && yarn typecheck", 14 | "test:unit": "jest", 15 | "test:package-types": "attw --pack . --entrypoints ./lib ./pure", 16 | "test:types": "zx ./tests/types/scripts/test.mjs", 17 | "update-ts-snapshot": "zx ./tests/types/scripts/update-ts-snapshot.mjs", 18 | "lint": "eslint '{src,types}/**/*.{ts,js}' && yarn prettier-check", 19 | "typecheck": "tsc", 20 | "copy-types": "./scripts/copy-types", 21 | "build": "yarn clean && yarn rollup -c && yarn copy-types", 22 | "clean": "rimraf dist", 23 | "prepublishOnly": "echo \"\nPlease use ./scripts/publish instead\n\" && exit 1", 24 | "prettier": "prettier './**/*.{js,ts,md,html,css}' --write", 25 | "prettier-check": "prettier './**/*.{js,ts,md,html,css}' --check" 26 | }, 27 | "keywords": [ 28 | "Stripe", 29 | "Stripe.js", 30 | "Elements" 31 | ], 32 | "author": "Stripe (https://www.stripe.com)", 33 | "license": "MIT", 34 | "homepage": "https://stripe.com/docs/js", 35 | "files": [ 36 | "dist", 37 | "lib", 38 | "pure", 39 | "src" 40 | ], 41 | "engines": { 42 | "node": ">=12.16" 43 | }, 44 | "devDependencies": { 45 | "@arethetypeswrong/cli": "^0.15.3", 46 | "@babel/core": "^7.7.2", 47 | "@babel/preset-env": "^7.7.1", 48 | "@rollup/plugin-replace": "^2.3.1", 49 | "@types/jest": "^24.0.25", 50 | "@types/node": "^16.6", 51 | "@typescript-eslint/eslint-plugin": "^4.15.2", 52 | "@typescript-eslint/parser": "^4.15.2", 53 | "babel-eslint": "^10.0.3", 54 | "babel-jest": "^24.9.0", 55 | "conditional-type-checks": "^1.0.5", 56 | "eslint": "^6.8.0", 57 | "eslint-config-prettier": "^6.8.0", 58 | "eslint-plugin-import": "^2.18.2", 59 | "eslint-plugin-jest": "^22.6.3", 60 | "eslint-plugin-prettier": "^3.1.1", 61 | "jest": "^24.9.0", 62 | "prettier": "^1.19.1", 63 | "rimraf": "^2.6.2", 64 | "rollup": "^2.79.2", 65 | "rollup-plugin-babel": "^4.3.3", 66 | "rollup-plugin-typescript2": "^0.25.3", 67 | "ts-jest": "^24.3.0", 68 | "typescript": "~4.8.0", 69 | "zx": "^8.8.5" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/types/scripts/ts-version-snapshot.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "typescript": { 4 | "major": 5, 5 | "minor": 9, 6 | "patch": 3 7 | }, 8 | "nodeTypes": { 9 | "major": 25, 10 | "minor": 0, 11 | "patch": 3 12 | } 13 | }, 14 | { 15 | "typescript": { 16 | "major": 5, 17 | "minor": 8, 18 | "patch": 3 19 | }, 20 | "nodeTypes": { 21 | "major": 25, 22 | "minor": 0, 23 | "patch": 3 24 | } 25 | }, 26 | { 27 | "typescript": { 28 | "major": 5, 29 | "minor": 7, 30 | "patch": 3 31 | }, 32 | "nodeTypes": { 33 | "major": 25, 34 | "minor": 0, 35 | "patch": 3 36 | } 37 | }, 38 | { 39 | "typescript": { 40 | "major": 5, 41 | "minor": 6, 42 | "patch": 3 43 | }, 44 | "nodeTypes": { 45 | "major": 25, 46 | "minor": 0, 47 | "patch": 3 48 | } 49 | }, 50 | { 51 | "typescript": { 52 | "major": 5, 53 | "minor": 5, 54 | "patch": 4 55 | }, 56 | "nodeTypes": { 57 | "major": 25, 58 | "minor": 0, 59 | "patch": 3 60 | } 61 | }, 62 | { 63 | "typescript": { 64 | "major": 5, 65 | "minor": 4, 66 | "patch": 5 67 | }, 68 | "nodeTypes": { 69 | "major": 25, 70 | "minor": 0, 71 | "patch": 3 72 | } 73 | }, 74 | { 75 | "typescript": { 76 | "major": 5, 77 | "minor": 3, 78 | "patch": 3 79 | }, 80 | "nodeTypes": { 81 | "major": 25, 82 | "minor": 0, 83 | "patch": 3 84 | } 85 | }, 86 | { 87 | "typescript": { 88 | "major": 5, 89 | "minor": 2, 90 | "patch": 2 91 | }, 92 | "nodeTypes": { 93 | "major": 25, 94 | "minor": 0, 95 | "patch": 3 96 | } 97 | }, 98 | { 99 | "typescript": { 100 | "major": 5, 101 | "minor": 1, 102 | "patch": 6 103 | }, 104 | "nodeTypes": { 105 | "major": 24, 106 | "minor": 1, 107 | "patch": 0 108 | } 109 | }, 110 | { 111 | "typescript": { 112 | "major": 5, 113 | "minor": 0, 114 | "patch": 4 115 | }, 116 | "nodeTypes": { 117 | "major": 22, 118 | "minor": 13, 119 | "patch": 14 120 | } 121 | }, 122 | { 123 | "typescript": { 124 | "major": 4, 125 | "minor": 9, 126 | "patch": 5 127 | }, 128 | "nodeTypes": { 129 | "major": 22, 130 | "minor": 9, 131 | "patch": 3 132 | } 133 | } 134 | ] -------------------------------------------------------------------------------- /src/shared.test.ts: -------------------------------------------------------------------------------- 1 | import {validateLoadParams, findScript} from './shared'; 2 | 3 | describe('validateLoadParams', () => { 4 | const INVALID_INPUTS: any[] = [ 5 | [undefined], 6 | [false], 7 | [null], 8 | [true], 9 | [{}], 10 | [8], 11 | [{advancedFraud: true}], 12 | [{advancedFraudSignals: true, someOtherKey: true}], 13 | [{advancedFraudSignals: 'true'}], 14 | ]; 15 | 16 | test.each(INVALID_INPUTS)('throws on invalid input: %p', (input) => { 17 | expect(() => validateLoadParams(input)).toThrow('invalid load parameters'); 18 | }); 19 | 20 | test('validates valid input', () => { 21 | expect(validateLoadParams({advancedFraudSignals: true})).toEqual({ 22 | advancedFraudSignals: true, 23 | }); 24 | 25 | expect(validateLoadParams({advancedFraudSignals: false})).toEqual({ 26 | advancedFraudSignals: false, 27 | }); 28 | }); 29 | }); 30 | 31 | describe('findScript', () => { 32 | const CASES: Array<[string, boolean]> = [ 33 | ['https://js.stripe.com/v3?advancedFraudSignals=true', true], 34 | ['https://js.stripe.com/v3', true], 35 | ['https://js.stripe.com/v3/', true], 36 | ['https://js.stripe.com/v3/stripe.js', true], 37 | ['https://js.stripe.com/v2/stripe.js', false], 38 | ['https://js.stripe.com/versionname/stripe.js', true], 39 | ['https://js.stripe.com/versionname/stripe.js', true], 40 | ['https://js.stripe.com/versionname/', false], 41 | ['https://js.stripe.com/versionname', false], 42 | ['https://js.stripe.com/v2/', false], 43 | ['https://js.stripe.com/v2', false], 44 | ['https://js.stripe.com/v3?advancedFraudSignals=false', true], 45 | ['https://js.stripe.com/v3?ab=cd', true], 46 | ['https://js.stripe.com/v3/something.js', false], 47 | ['https://js.stripe.com/v3/something.js?advancedFraudSignals=false', false], 48 | ['https://js.stripe.com/v3/something.js?ab=cd', false], 49 | ['https://js.stripe.com/versionname/stripe.js?ab=cd', true], 50 | ]; 51 | 52 | afterEach(() => { 53 | for (const [url] of CASES) { 54 | const script = document.querySelector(`script[src="${url}"]`); 55 | 56 | if (script && script.parentElement) { 57 | script.parentElement.removeChild(script); 58 | } 59 | } 60 | 61 | delete window.Stripe; 62 | }); 63 | 64 | test.each(CASES)( 65 | 'findScript with ', 66 | (url, shouldBeFound) => { 67 | const script = document.createElement('script'); 68 | script.src = url; 69 | document.body.appendChild(script); 70 | 71 | expect(!!findScript()).toBe(shouldBeFound); 72 | } 73 | ); 74 | }); 75 | -------------------------------------------------------------------------------- /types/api/bank-accounts.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * The BankAccount object. 3 | */ 4 | export interface BankAccount { 5 | /** 6 | * Unique identifier for the object. 7 | */ 8 | id: string; 9 | 10 | /** 11 | * String representing the object's type. Objects of the same type share the same value. 12 | */ 13 | object: 'bank_account'; 14 | 15 | /** 16 | * The name of the person or business that owns the bank account. 17 | */ 18 | account_holder_name: string | null; 19 | 20 | /** 21 | * The type of entity that holds the account. This can be either `individual` or `company`. 22 | */ 23 | account_holder_type: string | null; 24 | 25 | /** 26 | * Name of the bank associated with the routing number (e.g., `WELLS FARGO`). 27 | */ 28 | bank_name: string | null; 29 | 30 | /** 31 | * Two-letter ISO code representing the country the bank account is located in. 32 | */ 33 | country: string; 34 | 35 | /** 36 | * Three-letter [ISO code for the currency](https://stripe.com/docs/payouts) paid out to the bank account. 37 | */ 38 | currency: string; 39 | 40 | /** 41 | * Uniquely identifies this particular bank account. You can use this attribute to check whether two bank accounts are the same. 42 | */ 43 | fingerprint: string | null; 44 | 45 | /** 46 | * The last four digits of the bank account number. 47 | */ 48 | last4: string; 49 | 50 | /** 51 | * The routing transit number for the bank account. 52 | */ 53 | routing_number: string | null; 54 | 55 | /** 56 | * For bank accounts, possible values are `new`, `validated`, `verified`, `verification_failed`, or `errored`. A bank account that hasn't had any activity or validation performed is `new`. If Stripe can determine that the bank account exists, its status will be `validated`. Note that there often isn't enough information to know (e.g., for smaller credit unions), and the validation is not always run. If customer bank account verification has succeeded, the bank account status will be `verified`. If the verification failed for any reason, such as microdeposit failure, the status will be `verification_failed`. If a transfer sent to this bank account fails, we'll set the status to `errored` and will not continue to send transfers until the bank details are updated. 57 | * 58 | * For external accounts, possible values are `new` and `errored`. Validations aren't run against external accounts because they're only used for payouts. This means the other statuses don't apply. If a transfer fails, the status is set to `errored` and transfers are stopped until account details are updated. 59 | */ 60 | status: string; 61 | } 62 | -------------------------------------------------------------------------------- /types/api/shared.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. 3 | */ 4 | export interface Metadata { 5 | [name: string]: string; 6 | } 7 | 8 | /** 9 | * Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. 10 | * While you can send values as numbers, they will be returned as strings. 11 | */ 12 | export interface MetadataParam { 13 | [name: string]: string | number | null; 14 | } 15 | 16 | /** 17 | * The Address object. 18 | */ 19 | export interface Address { 20 | /** 21 | * City/District/Suburb/Town/Village. 22 | */ 23 | city: string | null; 24 | 25 | /** 26 | * 2-letter country code. 27 | */ 28 | country: string | null; 29 | 30 | /** 31 | * Address line 1 (Street address/PO Box/Company name). 32 | */ 33 | line1: string | null; 34 | 35 | /** 36 | * Address line 2 (Apartment/Suite/Unit/Building). 37 | */ 38 | line2: string | null; 39 | 40 | /** 41 | * ZIP or postal code. 42 | */ 43 | postal_code: string | null; 44 | 45 | /** 46 | * State/County/Province/Region. 47 | */ 48 | state: string | null; 49 | } 50 | 51 | export interface AccountAddressParam { 52 | /** 53 | * City, district, suburb, town, or village. 54 | */ 55 | city?: string; 56 | 57 | /** 58 | * Two-letter country code ([ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)). 59 | */ 60 | country?: string; 61 | 62 | /** 63 | * Address line 1 (e.g., street, PO Box, or company name). 64 | */ 65 | line1?: string; 66 | 67 | /** 68 | * Address line 2 (e.g., apartment, suite, unit, or building). 69 | */ 70 | line2?: string; 71 | 72 | /** 73 | * ZIP or postal code. 74 | */ 75 | postal_code?: string; 76 | 77 | /** 78 | * State, county, province, or region. 79 | */ 80 | state?: string; 81 | } 82 | 83 | export interface AddressParam extends AccountAddressParam { 84 | /** 85 | * Address line 1 (e.g., street, PO Box, or company name). 86 | */ 87 | line1: string; 88 | } 89 | 90 | export interface JapanAddressParam { 91 | /** 92 | * City or ward. 93 | */ 94 | city?: string; 95 | 96 | /** 97 | * Two-letter country code ([ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)). 98 | */ 99 | country?: string; 100 | 101 | /** 102 | * Block or building number. 103 | */ 104 | line1?: string; 105 | 106 | /** 107 | * Building details. 108 | */ 109 | line2?: string; 110 | 111 | /** 112 | * Postal code. 113 | */ 114 | postal_code?: string; 115 | 116 | /** 117 | * Prefecture. 118 | */ 119 | state?: string; 120 | 121 | /** 122 | * Town or cho-me. 123 | */ 124 | town?: string; 125 | } 126 | -------------------------------------------------------------------------------- /types/stripe-js/elements/currency-selector.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase} from './base'; 2 | import {StripeError} from '../stripe'; 3 | 4 | export type StripeCurrencySelectorElement = StripeElementBase & { 5 | /** 6 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 7 | */ 8 | on( 9 | eventType: 'ready', 10 | handler: (event: {elementType: 'currencySelector'}) => any 11 | ): StripeCurrencySelectorElement; 12 | once( 13 | eventType: 'ready', 14 | handler: (event: {elementType: 'currencySelector'}) => any 15 | ): StripeCurrencySelectorElement; 16 | off( 17 | eventType: 'ready', 18 | handler?: (event: {elementType: 'currencySelector'}) => any 19 | ): StripeCurrencySelectorElement; 20 | 21 | /** 22 | * Triggered when the element gains focus. 23 | */ 24 | on( 25 | eventType: 'focus', 26 | handler: (event: {elementType: 'currencySelector'}) => any 27 | ): StripeCurrencySelectorElement; 28 | once( 29 | eventType: 'focus', 30 | handler: (event: {elementType: 'currencySelector'}) => any 31 | ): StripeCurrencySelectorElement; 32 | off( 33 | eventType: 'focus', 34 | handler?: (event: {elementType: 'currencySelector'}) => any 35 | ): StripeCurrencySelectorElement; 36 | 37 | /** 38 | * Triggered when the element loses focus. 39 | */ 40 | on( 41 | eventType: 'blur', 42 | handler: (event: {elementType: 'currencySelector'}) => any 43 | ): StripeCurrencySelectorElement; 44 | once( 45 | eventType: 'blur', 46 | handler: (event: {elementType: 'currencySelector'}) => any 47 | ): StripeCurrencySelectorElement; 48 | off( 49 | eventType: 'blur', 50 | handler?: (event: {elementType: 'currencySelector'}) => any 51 | ): StripeCurrencySelectorElement; 52 | 53 | /** 54 | * Triggered when the escape key is pressed within the element. 55 | */ 56 | on( 57 | eventType: 'escape', 58 | handler: (event: {elementType: 'currencySelector'}) => any 59 | ): StripeCurrencySelectorElement; 60 | once( 61 | eventType: 'escape', 62 | handler: (event: {elementType: 'currencySelector'}) => any 63 | ): StripeCurrencySelectorElement; 64 | off( 65 | eventType: 'escape', 66 | handler?: (event: {elementType: 'currencySelector'}) => any 67 | ): StripeCurrencySelectorElement; 68 | 69 | /** 70 | * Triggered when the element fails to load. 71 | */ 72 | on( 73 | eventType: 'loaderror', 74 | handler: (event: { 75 | elementType: 'currencySelector'; 76 | error: StripeError; 77 | }) => any 78 | ): StripeCurrencySelectorElement; 79 | once( 80 | eventType: 'loaderror', 81 | handler: (event: { 82 | elementType: 'currencySelector'; 83 | error: StripeError; 84 | }) => any 85 | ): StripeCurrencySelectorElement; 86 | off( 87 | eventType: 'loaderror', 88 | handler?: (event: { 89 | elementType: 'currencySelector'; 90 | error: StripeError; 91 | }) => any 92 | ): StripeCurrencySelectorElement; 93 | }; 94 | -------------------------------------------------------------------------------- /types/stripe-js/elements/payment-method-messaging.d.ts: -------------------------------------------------------------------------------- 1 | export type StripePaymentMethodMessagingElement = { 2 | /** 3 | * The `element.mount` method attaches your [Element](https://stripe.com/docs/js/element) to the DOM. 4 | * `element.mount` accepts either a CSS Selector (e.g., `'#payment-method-messaging'`) or a DOM element. 5 | */ 6 | mount(domElement: string | HTMLElement): void; 7 | 8 | /** 9 | * Removes the element from the DOM and destroys it. 10 | * A destroyed element can not be re-activated or re-mounted to the DOM. 11 | */ 12 | destroy(): void; 13 | 14 | /** 15 | * Unmounts the element from the DOM. 16 | * Call `element.mount` to re-attach it to the DOM. 17 | */ 18 | unmount(): void; 19 | 20 | /** 21 | * Updates the options the `PaymentMethodMessagingElement` was initialized with. 22 | * Updates are merged into the existing configuration. 23 | */ 24 | update(options: Partial): void; 25 | 26 | /** 27 | * Triggered when the element is fully loaded and ready to perform method calls. 28 | */ 29 | on( 30 | eventType: 'ready', 31 | handler: (event: {elementType: 'paymentMethodMessaging'}) => any 32 | ): StripePaymentMethodMessagingElement; 33 | }; 34 | 35 | export interface StripePaymentMethodMessagingElementOptions { 36 | /** 37 | * The total amount in the smallest currency unit. 38 | */ 39 | amount: number; 40 | 41 | /** 42 | * The currency to display. 43 | */ 44 | currency: 45 | | 'AUD' 46 | | 'CAD' 47 | | 'CHF' 48 | | 'CZK' 49 | | 'DKK' 50 | | 'EUR' 51 | | 'GBP' 52 | | 'NOK' 53 | | 'NZD' 54 | | 'PLN' 55 | | 'SEK' 56 | | 'USD'; 57 | 58 | /** 59 | * Payment methods to show messaging for. 60 | */ 61 | paymentMethodTypes?: Array<'afterpay_clearpay' | 'klarna' | 'affirm'>; 62 | 63 | /** 64 | * Override the order in which payment methods are displayed in the Payment Method Messaging Element. 65 | * By default, the Payment Method Messaging Element will use a dynamic ordering that optimizes payment method display for each user. 66 | */ 67 | paymentMethodOrder?: Array<'afterpay_clearpay' | 'klarna' | 'affirm'>; 68 | 69 | /** 70 | * @deprecated Use `paymentMethodTypes` instead. 71 | */ 72 | paymentMethods?: Array<'afterpay_clearpay' | 'klarna' | 'affirm'>; 73 | 74 | /** 75 | * The country the end-buyer is in. 76 | */ 77 | countryCode?: 78 | | 'AT' 79 | | 'AU' 80 | | 'BE' 81 | | 'CA' 82 | | 'CH' 83 | | 'CZ' 84 | | 'DE' 85 | | 'DK' 86 | | 'ES' 87 | | 'FI' 88 | | 'FR' 89 | | 'GB' 90 | | 'GR' 91 | | 'IE' 92 | | 'IT' 93 | | 'NL' 94 | | 'NO' 95 | | 'NZ' 96 | | 'PL' 97 | | 'PT' 98 | | 'RO' 99 | | 'SE' 100 | | 'US'; 101 | 102 | /** 103 | * The logo color to display in the message. Defaults to black 104 | */ 105 | logoColor?: 'black' | 'white' | 'color'; 106 | 107 | metaData?: { 108 | messagingClientReferenceId: string | null; 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /types/stripe-js/token-and-sources.d.ts: -------------------------------------------------------------------------------- 1 | import {SourceCreateParams} from '../api'; 2 | 3 | /** 4 | * An object containing the unique ID and client secret for a `Source`. 5 | * 6 | * You can use a `Source` object created with `stripe.createSource` as the argument to `stripe.retrieveSource`, as every `Source` object has both `id` and `client_secret` keys. 7 | */ 8 | export interface RetrieveSourceParam { 9 | /** 10 | * Unique identifier of the `Source`. 11 | */ 12 | id: string; 13 | 14 | /** 15 | * A secret available to the web client that created the `Source`, for purposes of retrieving the `Source` later from that same client. 16 | */ 17 | client_secret: string; 18 | } 19 | 20 | /** 21 | * An object containing additional payment information you might have collected. 22 | * 23 | * Although these fields are optional, we highly recommend collecting name and address. 24 | * This information can be used to perform a number of verifications, such as CVC, ZIP, and address verification. 25 | * Radar includes built-in rules that can block payments where the ZIP or CVC verifications with the cardholder’s bank failed. 26 | */ 27 | export interface CreateTokenCardData { 28 | /** 29 | * @recommended 30 | */ 31 | name?: string; 32 | 33 | address_line1?: string; 34 | 35 | address_line2?: string; 36 | 37 | address_city?: string; 38 | 39 | address_state?: string; 40 | 41 | address_zip?: string; 42 | 43 | /** 44 | * A two character country code (for example, `US`). 45 | * 46 | * @recommended 47 | */ 48 | address_country?: string; 49 | 50 | /** 51 | * Required in order to [add the card to a Connect account](https://stripe.com/docs/connect/payouts#bank-accounts) (in all other cases, this parameter is not used). 52 | * Currently, the only supported currency for debit card payouts is `usd`. 53 | */ 54 | currency?: string; 55 | } 56 | 57 | export interface CreateTokenIbanData { 58 | /** 59 | * Three character currency code (e.g., `eur`). 60 | */ 61 | currency: string; 62 | 63 | account_holder_name: string; 64 | 65 | account_holder_type: string; 66 | } 67 | 68 | export interface CreateTokenPiiData { 69 | personal_id_number: string; 70 | } 71 | 72 | export interface CreateTokenBankAccountData { 73 | country: string; 74 | 75 | currency: string; 76 | 77 | routing_number?: string; 78 | 79 | account_number: string; 80 | 81 | account_holder_name?: string; 82 | 83 | account_holder_type: string; 84 | 85 | account_type?: string; 86 | } 87 | 88 | /** 89 | * A required object containing the `type` of `Source` you want to create, and any additional payment information that you have collected. 90 | * See the [Sources API](https://stripe.com/docs/api#create_source) reference for details. 91 | * 92 | * You cannot pass raw card information to `stripe.createSource(sourceData)`. 93 | * Instead, you must gather card information in an `Element` and use `stripe.createSource(element, sourceData)`. 94 | * You can also pass an existing card token to convert it into a `Source` object. 95 | */ 96 | export interface CreateSourceData extends SourceCreateParams { 97 | bancontact?: CreateSourceData.DeprecatedMethodData; 98 | 99 | ideal?: CreateSourceData.DeprecatedMethodData; 100 | 101 | klarna?: CreateSourceData.DeprecatedMethodData; 102 | 103 | sepa_debit?: CreateSourceData.DeprecatedMethodData; 104 | 105 | sofort?: CreateSourceData.DeprecatedMethodData; 106 | } 107 | 108 | export namespace CreateSourceData { 109 | export type DeprecatedMethodData = Record; 110 | } 111 | -------------------------------------------------------------------------------- /types/stripe-js/elements/card-cvc.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | 8 | export type StripeCardCvcElement = StripeElementBase & { 9 | /** 10 | * The change event is triggered when the `Element`'s value changes. 11 | */ 12 | on( 13 | eventType: 'change', 14 | handler: (event: StripeCardCvcElementChangeEvent) => any 15 | ): StripeCardCvcElement; 16 | once( 17 | eventType: 'change', 18 | handler: (event: StripeCardCvcElementChangeEvent) => any 19 | ): StripeCardCvcElement; 20 | off( 21 | eventType: 'change', 22 | handler?: (event: StripeCardCvcElementChangeEvent) => any 23 | ): StripeCardCvcElement; 24 | 25 | /** 26 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 27 | */ 28 | on( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'cardCvc'}) => any 31 | ): StripeCardCvcElement; 32 | once( 33 | eventType: 'ready', 34 | handler: (event: {elementType: 'cardCvc'}) => any 35 | ): StripeCardCvcElement; 36 | off( 37 | eventType: 'ready', 38 | handler?: (event: {elementType: 'cardCvc'}) => any 39 | ): StripeCardCvcElement; 40 | 41 | /** 42 | * Triggered when the element gains focus. 43 | */ 44 | on( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'cardCvc'}) => any 47 | ): StripeCardCvcElement; 48 | once( 49 | eventType: 'focus', 50 | handler: (event: {elementType: 'cardCvc'}) => any 51 | ): StripeCardCvcElement; 52 | off( 53 | eventType: 'focus', 54 | handler?: (event: {elementType: 'cardCvc'}) => any 55 | ): StripeCardCvcElement; 56 | 57 | /** 58 | * Triggered when the element loses focus. 59 | */ 60 | on( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'cardCvc'}) => any 63 | ): StripeCardCvcElement; 64 | once( 65 | eventType: 'blur', 66 | handler: (event: {elementType: 'cardCvc'}) => any 67 | ): StripeCardCvcElement; 68 | off( 69 | eventType: 'blur', 70 | handler?: (event: {elementType: 'cardCvc'}) => any 71 | ): StripeCardCvcElement; 72 | 73 | /** 74 | * Triggered when the escape key is pressed within the element. 75 | */ 76 | on( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'cardCvc'}) => any 79 | ): StripeCardCvcElement; 80 | once( 81 | eventType: 'escape', 82 | handler: (event: {elementType: 'cardCvc'}) => any 83 | ): StripeCardCvcElement; 84 | off( 85 | eventType: 'escape', 86 | handler?: (event: {elementType: 'cardCvc'}) => any 87 | ): StripeCardCvcElement; 88 | 89 | /** 90 | * Updates the options the `CardCvcElement` was initialized with. 91 | * Updates are merged into the existing configuration. 92 | * 93 | * The styles of an `CardCvcElement` can be dynamically changed using `element.update`. 94 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 95 | */ 96 | update(options: Partial): void; 97 | }; 98 | 99 | export interface StripeCardCvcElementOptions { 100 | classes?: StripeElementClasses; 101 | 102 | style?: StripeElementStyle; 103 | 104 | placeholder?: string; 105 | 106 | /** 107 | * Applies a disabled state to the Element such that user input is not accepted. 108 | * Default is false. 109 | */ 110 | disabled?: boolean; 111 | } 112 | 113 | export interface StripeCardCvcElementChangeEvent 114 | extends StripeElementChangeEvent { 115 | /** 116 | * The type of element that emitted this event. 117 | */ 118 | elementType: 'cardCvc'; 119 | } 120 | -------------------------------------------------------------------------------- /types/api/orders.d.ts: -------------------------------------------------------------------------------- 1 | import {Address} from './shared'; 2 | import {PaymentIntent} from './payment-intents'; 3 | 4 | /** 5 | * The Order object. 6 | */ 7 | export interface Order { 8 | /** 9 | * Unique identifier for the object. 10 | */ 11 | id: string; 12 | 13 | /** 14 | * String representing the object's type. Objects of the same type share the same value. 15 | */ 16 | object: 'order'; 17 | 18 | /** 19 | * Total order cost after discounts and taxes are applied. A positive integer representing how much to charge in the [smallest currency unit](https://stripe.com/docs/currencies#zero-decimal) (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency). To submit an order, the total must be either 0 or at least $0.50 USD or [equivalent in charge currency](https://stripe.com/docs/currencies#minimum-and-maximum-charge-amounts). 20 | */ 21 | amount_total: number; 22 | 23 | /** 24 | * Order cost before any discounts or taxes are applied. A positive integer representing how much to charge in the [smallest currency unit](https://stripe.com/docs/currencies#zero-decimal) (e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal currency). 25 | */ 26 | amount_subtotal: number; 27 | 28 | /** 29 | * Customer billing details associated with the order. 30 | */ 31 | billing_details: Order.Billing | null; 32 | 33 | /** 34 | * Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. Must be a [supported currency](https://stripe.com/docs/currencies). 35 | */ 36 | currency: string; 37 | 38 | /** 39 | * Time at which the object was created. Measured in seconds since the Unix epoch. 40 | */ 41 | created: number; 42 | 43 | /** 44 | * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. 45 | */ 46 | livemode: boolean; 47 | 48 | /** 49 | * Customer shipping information associated with the order. 50 | */ 51 | shipping_details: Order.Shipping | null; 52 | 53 | /** 54 | * Payment information associated with the order. 55 | */ 56 | payment: Order.Payment; 57 | 58 | /** 59 | * The overall status of the order. 60 | */ 61 | status: Order.Status; 62 | } 63 | 64 | export namespace Order { 65 | export interface Billing { 66 | /** 67 | * Billing address for the order. 68 | */ 69 | address?: Address; 70 | 71 | /** 72 | * Email address for the order. 73 | */ 74 | email?: string | null; 75 | 76 | /** 77 | * Full name for the order. 78 | */ 79 | name?: string | null; 80 | 81 | /** 82 | * Billing phone number for the order (including extension). 83 | */ 84 | phone?: string | null; 85 | } 86 | 87 | export interface Shipping { 88 | /** 89 | * Recipient shipping address. Required if the order includes products that are shippable. 90 | */ 91 | address?: Address; 92 | 93 | /** 94 | * Recipient name. 95 | */ 96 | name?: string | null; 97 | 98 | /** 99 | * Recipient phone (including extension). 100 | */ 101 | phone?: string | null; 102 | } 103 | 104 | export interface Payment { 105 | /** 106 | * Payment intent associated with this order. Null when the order is `open`. 107 | */ 108 | payment_intent?: PaymentIntent | null; 109 | 110 | /** 111 | * The status of the underlying payment associated with this order, if any. Null when the order is `open`. 112 | */ 113 | status?: PaymentIntent.Status | null; 114 | } 115 | 116 | export type Status = 117 | | 'open' 118 | | 'submitted' 119 | | 'processing' 120 | | 'complete' 121 | | 'canceled'; 122 | } 123 | -------------------------------------------------------------------------------- /types/stripe-js/elements/card-expiry.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | 8 | export type StripeCardExpiryElement = StripeElementBase & { 9 | /** 10 | * The change event is triggered when the `Element`'s value changes. 11 | */ 12 | on( 13 | eventType: 'change', 14 | handler: (event: StripeCardExpiryElementChangeEvent) => any 15 | ): StripeCardExpiryElement; 16 | once( 17 | eventType: 'change', 18 | handler: (event: StripeCardExpiryElementChangeEvent) => any 19 | ): StripeCardExpiryElement; 20 | off( 21 | eventType: 'change', 22 | handler?: (event: StripeCardExpiryElementChangeEvent) => any 23 | ): StripeCardExpiryElement; 24 | 25 | /** 26 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 27 | */ 28 | on( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'cardExpiry'}) => any 31 | ): StripeCardExpiryElement; 32 | once( 33 | eventType: 'ready', 34 | handler: (event: {elementType: 'cardExpiry'}) => any 35 | ): StripeCardExpiryElement; 36 | off( 37 | eventType: 'ready', 38 | handler?: (event: {elementType: 'cardExpiry'}) => any 39 | ): StripeCardExpiryElement; 40 | 41 | /** 42 | * Triggered when the element gains focus. 43 | */ 44 | on( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'cardExpiry'}) => any 47 | ): StripeCardExpiryElement; 48 | once( 49 | eventType: 'focus', 50 | handler: (event: {elementType: 'cardExpiry'}) => any 51 | ): StripeCardExpiryElement; 52 | off( 53 | eventType: 'focus', 54 | handler?: (event: {elementType: 'cardExpiry'}) => any 55 | ): StripeCardExpiryElement; 56 | 57 | /** 58 | * Triggered when the element loses focus. 59 | */ 60 | on( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'cardExpiry'}) => any 63 | ): StripeCardExpiryElement; 64 | once( 65 | eventType: 'blur', 66 | handler: (event: {elementType: 'cardExpiry'}) => any 67 | ): StripeCardExpiryElement; 68 | off( 69 | eventType: 'blur', 70 | handler?: (event: {elementType: 'cardExpiry'}) => any 71 | ): StripeCardExpiryElement; 72 | 73 | /** 74 | * Triggered when the escape key is pressed within the element. 75 | */ 76 | on( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'cardExpiry'}) => any 79 | ): StripeCardExpiryElement; 80 | once( 81 | eventType: 'escape', 82 | handler: (event: {elementType: 'cardExpiry'}) => any 83 | ): StripeCardExpiryElement; 84 | off( 85 | eventType: 'escape', 86 | handler?: (event: {elementType: 'cardExpiry'}) => any 87 | ): StripeCardExpiryElement; 88 | 89 | /** 90 | * Updates the options the `CardExpiryElement` was initialized with. 91 | * Updates are merged into the existing configuration. 92 | * 93 | * The styles of an `CardExpiryElement` can be dynamically changed using `element.update`. 94 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 95 | */ 96 | update(options: Partial): void; 97 | }; 98 | 99 | export interface StripeCardExpiryElementOptions { 100 | classes?: StripeElementClasses; 101 | 102 | style?: StripeElementStyle; 103 | 104 | placeholder?: string; 105 | 106 | /** 107 | * Applies a disabled state to the Element such that user input is not accepted. 108 | * Default is false. 109 | */ 110 | disabled?: boolean; 111 | } 112 | 113 | export interface StripeCardExpiryElementChangeEvent 114 | extends StripeElementChangeEvent { 115 | /** 116 | * The type of element that emitted this event. 117 | */ 118 | elementType: 'cardExpiry'; 119 | } 120 | -------------------------------------------------------------------------------- /types/api/cards.d.ts: -------------------------------------------------------------------------------- 1 | import {Metadata} from './shared'; 2 | 3 | /** 4 | * The Card object. 5 | */ 6 | export interface Card { 7 | /** 8 | * Unique identifier for the object. 9 | */ 10 | id: string; 11 | 12 | /** 13 | * String representing the object's type. Objects of the same type share the same value. 14 | */ 15 | object: 'card'; 16 | 17 | /** 18 | * City/District/Suburb/Town/Village. 19 | */ 20 | address_city: string | null; 21 | 22 | /** 23 | * Billing address country, if provided when creating card. 24 | */ 25 | address_country: string | null; 26 | 27 | /** 28 | * Address line 1 (Street address/PO Box/Company name). 29 | */ 30 | address_line1: string | null; 31 | 32 | /** 33 | * If `address_line1` was provided, results of the check: `pass`, `fail`, `unavailable`, or `unchecked`. 34 | */ 35 | address_line1_check: string | null; 36 | 37 | /** 38 | * Address line 2 (Apartment/Suite/Unit/Building). 39 | */ 40 | address_line2: string | null; 41 | 42 | /** 43 | * State/County/Province/Region. 44 | */ 45 | address_state: string | null; 46 | 47 | /** 48 | * ZIP or postal code. 49 | */ 50 | address_zip: string | null; 51 | 52 | /** 53 | * If `address_zip` was provided, results of the check: `pass`, `fail`, `unavailable`, or `unchecked`. 54 | */ 55 | address_zip_check: string | null; 56 | 57 | /** 58 | * Card brand. Can be `American Express`, `Diners Club`, `Discover`, `JCB`, `MasterCard`, `UnionPay`, `Visa`, or `Unknown`. 59 | */ 60 | brand: string; 61 | 62 | /** 63 | * Two-letter ISO code representing the country of the card. You could use this attribute to get a sense of the international breakdown of cards you've collected. 64 | */ 65 | country: string | null; 66 | 67 | /** 68 | * Three-letter [ISO currency code](https://www.iso.org/iso-4217-currency-codes.html), in lowercase. Must be a [supported currency](https://stripe.com/docs/currencies). 69 | */ 70 | currency?: string | null; 71 | 72 | /** 73 | * The customer that this card belongs to. This attribute will not be in the card object if the card belongs to an account or recipient instead. 74 | */ 75 | customer?: string | null; 76 | 77 | /** 78 | * If a CVC was provided, results of the check: `pass`, `fail`, `unavailable`, or `unchecked`. 79 | */ 80 | cvc_check: string | null; 81 | 82 | /** 83 | * (For tokenized numbers only.) The last four digits of the device account number. 84 | */ 85 | dynamic_last4: string | null; 86 | 87 | /** 88 | * Two-digit number representing the card's expiration month. 89 | */ 90 | exp_month: number; 91 | 92 | /** 93 | * Four-digit number representing the card's expiration year. 94 | */ 95 | exp_year: number; 96 | 97 | /** 98 | * Uniquely identifies this particular card number. You can use this attribute to check whether two customers who've signed up with you are using the same card number, for example. 99 | */ 100 | fingerprint?: string | null; 101 | 102 | /** 103 | * Card funding type. Can be `credit`, `debit`, `prepaid`, or `unknown`. 104 | */ 105 | funding: string; 106 | 107 | /** 108 | * The last four digits of the card. 109 | */ 110 | last4: string; 111 | 112 | /** 113 | * Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. 114 | */ 115 | metadata: Metadata; 116 | 117 | /** 118 | * Cardholder name. 119 | */ 120 | name: string | null; 121 | 122 | /** 123 | * If the card number is tokenized, this is the method that was used. Can be `apple_pay` or `google_pay`. 124 | */ 125 | tokenization_method: string | null; 126 | } 127 | 128 | export namespace Card { 129 | export type AvailablePayoutMethod = 'instant' | 'standard'; 130 | } 131 | -------------------------------------------------------------------------------- /types/stripe-js/elements/iban.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | 8 | export type StripeIbanElement = StripeElementBase & { 9 | /** 10 | * The change event is triggered when the `Element`'s value changes. 11 | */ 12 | on( 13 | eventType: 'change', 14 | handler: (event: StripeIbanElementChangeEvent) => any 15 | ): StripeIbanElement; 16 | once( 17 | eventType: 'change', 18 | handler: (event: StripeIbanElementChangeEvent) => any 19 | ): StripeIbanElement; 20 | off( 21 | eventType: 'change', 22 | handler?: (event: StripeIbanElementChangeEvent) => any 23 | ): StripeIbanElement; 24 | 25 | /** 26 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 27 | */ 28 | on( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'iban'}) => any 31 | ): StripeIbanElement; 32 | once( 33 | eventType: 'ready', 34 | handler: (event: {elementType: 'iban'}) => any 35 | ): StripeIbanElement; 36 | off( 37 | eventType: 'ready', 38 | handler?: (event: {elementType: 'iban'}) => any 39 | ): StripeIbanElement; 40 | 41 | /** 42 | * Triggered when the element gains focus. 43 | */ 44 | on( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'iban'}) => any 47 | ): StripeIbanElement; 48 | once( 49 | eventType: 'focus', 50 | handler: (event: {elementType: 'iban'}) => any 51 | ): StripeIbanElement; 52 | off( 53 | eventType: 'focus', 54 | handler?: (event: {elementType: 'iban'}) => any 55 | ): StripeIbanElement; 56 | 57 | /** 58 | * Triggered when the element loses focus. 59 | */ 60 | on( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'iban'}) => any 63 | ): StripeIbanElement; 64 | once( 65 | eventType: 'blur', 66 | handler: (event: {elementType: 'iban'}) => any 67 | ): StripeIbanElement; 68 | off( 69 | eventType: 'blur', 70 | handler?: (event: {elementType: 'iban'}) => any 71 | ): StripeIbanElement; 72 | 73 | /** 74 | * Triggered when the escape key is pressed within the element. 75 | */ 76 | on( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'iban'}) => any 79 | ): StripeIbanElement; 80 | once( 81 | eventType: 'escape', 82 | handler: (event: {elementType: 'iban'}) => any 83 | ): StripeIbanElement; 84 | off( 85 | eventType: 'escape', 86 | handler?: (event: {elementType: 'iban'}) => any 87 | ): StripeIbanElement; 88 | 89 | /** 90 | * Updates the options the `IbanElement` was initialized with. 91 | * Updates are merged into the existing configuration. 92 | * 93 | * The styles of an `IbanElement` can be dynamically changed using `element.update`. 94 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 95 | */ 96 | update(options: Partial): void; 97 | }; 98 | 99 | export interface StripeIbanElementOptions { 100 | classes?: StripeElementClasses; 101 | 102 | style?: StripeElementStyle; 103 | 104 | supportedCountries?: string[]; 105 | 106 | placeholderCountry?: string; 107 | 108 | /** 109 | * Appearance of the icon in the Element. 110 | */ 111 | iconStyle?: 'default' | 'solid'; 112 | 113 | /** 114 | * Hides the icon in the Element. 115 | * Default is `false`. 116 | */ 117 | hideIcon?: boolean; 118 | 119 | /** 120 | * Applies a disabled state to the Element such that user input is not accepted. 121 | * Default is false. 122 | */ 123 | disabled?: boolean; 124 | } 125 | 126 | export interface StripeIbanElementChangeEvent extends StripeElementChangeEvent { 127 | /** 128 | * The type of element that emitted this event. 129 | */ 130 | elementType: 'iban'; 131 | 132 | country: string; 133 | 134 | bankName: string; 135 | } 136 | -------------------------------------------------------------------------------- /types/stripe-js/elements/au-bank-account.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | 8 | export type StripeAuBankAccountElement = StripeElementBase & { 9 | /** 10 | * The change event is triggered when the `Element`'s value changes. 11 | */ 12 | on( 13 | eventType: 'change', 14 | handler: (event: StripeAuBankAccountElementChangeEvent) => any 15 | ): StripeAuBankAccountElement; 16 | once( 17 | eventType: 'change', 18 | handler: (event: StripeAuBankAccountElementChangeEvent) => any 19 | ): StripeAuBankAccountElement; 20 | off( 21 | eventType: 'change', 22 | handler?: (event: StripeAuBankAccountElementChangeEvent) => any 23 | ): StripeAuBankAccountElement; 24 | 25 | /** 26 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 27 | */ 28 | on( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'auBankAccount'}) => any 31 | ): StripeAuBankAccountElement; 32 | once( 33 | eventType: 'ready', 34 | handler: (event: {elementType: 'auBankAccount'}) => any 35 | ): StripeAuBankAccountElement; 36 | off( 37 | eventType: 'ready', 38 | handler?: (event: {elementType: 'auBankAccount'}) => any 39 | ): StripeAuBankAccountElement; 40 | 41 | /** 42 | * Triggered when the element gains focus. 43 | */ 44 | on( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'auBankAccount'}) => any 47 | ): StripeAuBankAccountElement; 48 | once( 49 | eventType: 'focus', 50 | handler: (event: {elementType: 'auBankAccount'}) => any 51 | ): StripeAuBankAccountElement; 52 | off( 53 | eventType: 'focus', 54 | handler?: (event: {elementType: 'auBankAccount'}) => any 55 | ): StripeAuBankAccountElement; 56 | 57 | /** 58 | * Triggered when the element loses focus. 59 | */ 60 | on( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'auBankAccount'}) => any 63 | ): StripeAuBankAccountElement; 64 | once( 65 | eventType: 'blur', 66 | handler: (event: {elementType: 'auBankAccount'}) => any 67 | ): StripeAuBankAccountElement; 68 | off( 69 | eventType: 'blur', 70 | handler?: (event: {elementType: 'auBankAccount'}) => any 71 | ): StripeAuBankAccountElement; 72 | 73 | /** 74 | * Triggered when the escape key is pressed within the element. 75 | */ 76 | on( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'auBankAccount'}) => any 79 | ): StripeAuBankAccountElement; 80 | once( 81 | eventType: 'escape', 82 | handler: (event: {elementType: 'auBankAccount'}) => any 83 | ): StripeAuBankAccountElement; 84 | off( 85 | eventType: 'escape', 86 | handler?: (event: {elementType: 'auBankAccount'}) => any 87 | ): StripeAuBankAccountElement; 88 | 89 | /** 90 | * Updates the options the `AuBankAccountElement` was initialized with. 91 | * Updates are merged into the existing configuration. 92 | * 93 | * The styles of an `AuBankAccountElement` can be dynamically changed using `element.update`. 94 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 95 | */ 96 | update(options: Partial): void; 97 | }; 98 | 99 | export interface StripeAuBankAccountElementOptions { 100 | classes?: StripeElementClasses; 101 | 102 | style?: StripeElementStyle; 103 | 104 | /** 105 | * Appearance of the icon in the Element. 106 | */ 107 | iconStyle?: 'default' | 'solid'; 108 | 109 | /** 110 | * Hides the icon in the Element. 111 | * Default is `false`. 112 | */ 113 | hideIcon?: boolean; 114 | 115 | /** 116 | * Applies a disabled state to the Element such that user input is not accepted. 117 | * Default is false. 118 | */ 119 | disabled?: boolean; 120 | } 121 | 122 | export interface StripeAuBankAccountElementChangeEvent 123 | extends StripeElementChangeEvent { 124 | /** 125 | * The type of element that emitted this event. 126 | */ 127 | elementType: 'auBankAccount'; 128 | 129 | /** 130 | * The bank name corresponding to the entered BSB. 131 | */ 132 | bankName?: string; 133 | 134 | /** 135 | * The branch name corresponding to the entered BSB. 136 | */ 137 | branchName?: string; 138 | } 139 | -------------------------------------------------------------------------------- /types/stripe-js/elements/apple-pay.d.ts: -------------------------------------------------------------------------------- 1 | export type ApplePayRecurringPaymentRequestIntervalUnit = 2 | | 'year' 3 | | 'month' 4 | | 'day' 5 | | 'hour' 6 | | 'minute'; 7 | 8 | export interface ApplePayLineItem { 9 | /** 10 | * A short, localized description of the line item. 11 | */ 12 | label: string; 13 | 14 | /** 15 | * The amount in the currency's subunit (e.g. cents, yen, etc.) 16 | */ 17 | amount: number; 18 | } 19 | 20 | export type ApplePayRegularBilling = ApplePayLineItem & { 21 | /** 22 | * The date of the first payment. 23 | */ 24 | recurringPaymentStartDate?: Date; 25 | 26 | /** 27 | * The date of the final payment. 28 | */ 29 | recurringPaymentEndDate?: Date; 30 | 31 | /** 32 | * The amount of time — in calendar units, such as day, month, or year — that represents a fraction of the total payment interval. 33 | */ 34 | recurringPaymentIntervalUnit?: ApplePayRecurringPaymentRequestIntervalUnit; 35 | 36 | /** 37 | * The number of interval units that make up the total payment interval. 38 | */ 39 | recurringPaymentIntervalCount?: number; 40 | }; 41 | 42 | export interface ApplePayRecurringPaymentRequest { 43 | /** 44 | * The description of the payment that the customer will see in their Apple Pay wallet. 45 | */ 46 | paymentDescription: string; 47 | 48 | /** 49 | * The URL to manage items related to the recurring payment on your website. 50 | */ 51 | managementURL: string; 52 | regularBilling: ApplePayRegularBilling; 53 | trialBilling?: ApplePayRegularBilling; 54 | 55 | /** 56 | * The billing agreement label that is displayed to the customer in the Apple Pay payment interface. 57 | */ 58 | billingAgreement?: string; 59 | } 60 | 61 | export type ApplePayAutomaticReloadBilling = ApplePayLineItem & { 62 | /** 63 | * The balance an account reaches before the merchant applies the automatic reload amount. 64 | */ 65 | automaticReloadPaymentThresholdAmount: number; 66 | }; 67 | 68 | export interface ApplePayAutomaticReloadPaymentRequest { 69 | /** 70 | * The description of the payment that the customer will see in their Apple Pay wallet. 71 | */ 72 | paymentDescription: string; 73 | 74 | /** 75 | * The URL to manage items related to the automatic reload payment on your website. 76 | */ 77 | managementURL: string; 78 | automaticReloadBilling: ApplePayAutomaticReloadBilling; 79 | 80 | /** 81 | * The billing agreement label that is displayed to the customer in the Apple Pay payment interface. 82 | */ 83 | billingAgreement?: string; 84 | } 85 | 86 | export type ApplePayDeferredBilling = ApplePayLineItem & { 87 | /** 88 | * The date, in the future, of the payment. 89 | */ 90 | deferredPaymentDate: Date; 91 | }; 92 | 93 | export interface ApplePayDeferredPaymentRequest { 94 | /** 95 | * The description of the payment that the customer will see in their Apple Pay wallet. 96 | */ 97 | paymentDescription: string; 98 | 99 | /** 100 | * The URL to manage items related to the deferred payment on your website. 101 | */ 102 | managementURL: string; 103 | deferredBilling: ApplePayDeferredBilling; 104 | 105 | /** 106 | * The billing agreement label that is displayed to the customer in the Apple Pay payment interface. 107 | */ 108 | billingAgreement?: string; 109 | 110 | /** 111 | * The future date before which the customer can cancel the deferred payment for free. 112 | */ 113 | freeCancellationDate?: Date; 114 | 115 | /** 116 | * The time zone of the free cancellation date. 117 | * 118 | * These are [tz](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) timezones such as `America/Los_Angeles`, `Europe/Dublin`, and `Asia/Singapore`. 119 | */ 120 | freeCancellationDateTimeZone?: string; 121 | } 122 | 123 | export type ApplePayOption = 124 | | { 125 | recurringPaymentRequest: ApplePayRecurringPaymentRequest; 126 | deferredPaymentRequest?: null; 127 | automaticReloadPaymentRequest?: null; 128 | } 129 | | { 130 | recurringPaymentRequest?: null; 131 | deferredPaymentRequest: ApplePayDeferredPaymentRequest; 132 | automaticReloadPaymentRequest?: null; 133 | } 134 | | { 135 | recurringPaymentRequest?: null; 136 | deferredPaymentRequest?: null; 137 | automaticReloadPaymentRequest: ApplePayAutomaticReloadPaymentRequest; 138 | } 139 | | { 140 | recurringPaymentRequest?: null; 141 | deferredPaymentRequest?: null; 142 | automaticReloadPaymentRequest?: null; 143 | }; 144 | 145 | export type ApplePayUpdateOption = 146 | | { 147 | recurringPaymentRequest: ApplePayRecurringPaymentRequest; 148 | automaticReloadPaymentRequest?: null; 149 | } 150 | | { 151 | recurringPaymentRequest?: null; 152 | automaticReloadPaymentRequest: ApplePayAutomaticReloadPaymentRequest; 153 | } 154 | | { 155 | recurringPaymentRequest?: null; 156 | automaticReloadPaymentRequest?: null; 157 | }; 158 | -------------------------------------------------------------------------------- /types/stripe-js/elements/link-authentication.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase} from './base'; 2 | import {StripeError} from '../stripe'; 3 | 4 | export type StripeLinkAuthenticationElement = StripeElementBase & { 5 | /** 6 | * The change event is triggered when the `Element`'s value changes. 7 | */ 8 | on( 9 | eventType: 'change', 10 | handler: (event: StripeLinkAuthenticationElementChangeEvent) => any 11 | ): StripeLinkAuthenticationElement; 12 | once( 13 | eventType: 'change', 14 | handler: (event: StripeLinkAuthenticationElementChangeEvent) => any 15 | ): StripeLinkAuthenticationElement; 16 | off( 17 | eventType: 'change', 18 | handler?: (event: StripeLinkAuthenticationElementChangeEvent) => any 19 | ): StripeLinkAuthenticationElement; 20 | 21 | /** 22 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 23 | */ 24 | on( 25 | eventType: 'ready', 26 | handler: (event: {elementType: 'linkAuthentication'}) => any 27 | ): StripeLinkAuthenticationElement; 28 | once( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'linkAuthentication'}) => any 31 | ): StripeLinkAuthenticationElement; 32 | off( 33 | eventType: 'ready', 34 | handler?: (event: {elementType: 'linkAuthentication'}) => any 35 | ): StripeLinkAuthenticationElement; 36 | 37 | /** 38 | * Triggered when the element gains focus. 39 | */ 40 | on( 41 | eventType: 'focus', 42 | handler: (event: {elementType: 'linkAuthentication'}) => any 43 | ): StripeLinkAuthenticationElement; 44 | once( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'linkAuthentication'}) => any 47 | ): StripeLinkAuthenticationElement; 48 | off( 49 | eventType: 'focus', 50 | handler?: (event: {elementType: 'linkAuthentication'}) => any 51 | ): StripeLinkAuthenticationElement; 52 | 53 | /** 54 | * Triggered when the element loses focus. 55 | */ 56 | on( 57 | eventType: 'blur', 58 | handler: (event: {elementType: 'linkAuthentication'}) => any 59 | ): StripeLinkAuthenticationElement; 60 | once( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'linkAuthentication'}) => any 63 | ): StripeLinkAuthenticationElement; 64 | off( 65 | eventType: 'blur', 66 | handler?: (event: {elementType: 'linkAuthentication'}) => any 67 | ): StripeLinkAuthenticationElement; 68 | 69 | /** 70 | * Triggered when the escape key is pressed within the element. 71 | */ 72 | on( 73 | eventType: 'escape', 74 | handler: (event: {elementType: 'linkAuthentication'}) => any 75 | ): StripeLinkAuthenticationElement; 76 | once( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'linkAuthentication'}) => any 79 | ): StripeLinkAuthenticationElement; 80 | off( 81 | eventType: 'escape', 82 | handler?: (event: {elementType: 'linkAuthentication'}) => any 83 | ): StripeLinkAuthenticationElement; 84 | 85 | /** 86 | * Triggered when the element fails to load. 87 | */ 88 | on( 89 | eventType: 'loaderror', 90 | handler: (event: { 91 | elementType: 'linkAuthentication'; 92 | error: StripeError; 93 | }) => any 94 | ): StripeLinkAuthenticationElement; 95 | once( 96 | eventType: 'loaderror', 97 | handler: (event: { 98 | elementType: 'linkAuthentication'; 99 | error: StripeError; 100 | }) => any 101 | ): StripeLinkAuthenticationElement; 102 | off( 103 | eventType: 'loaderror', 104 | handler?: (event: { 105 | elementType: 'linkAuthentication'; 106 | error: StripeError; 107 | }) => any 108 | ): StripeLinkAuthenticationElement; 109 | 110 | /** 111 | * Triggered when the loader UI is mounted to the DOM and ready to be displayed. 112 | */ 113 | on( 114 | eventType: 'loaderstart', 115 | handler: (event: {elementType: 'linkAuthentication'}) => any 116 | ): StripeLinkAuthenticationElement; 117 | once( 118 | eventType: 'loaderstart', 119 | handler: (event: {elementType: 'linkAuthentication'}) => any 120 | ): StripeLinkAuthenticationElement; 121 | off( 122 | eventType: 'loaderstart', 123 | handler?: (event: {elementType: 'linkAuthentication'}) => any 124 | ): StripeLinkAuthenticationElement; 125 | }; 126 | 127 | export interface StripeLinkAuthenticationElementOptions { 128 | /** 129 | * Default value for LinkAuthenticationElement fields 130 | */ 131 | defaultValues?: { 132 | email: string; 133 | }; 134 | } 135 | 136 | export interface StripeLinkAuthenticationElementChangeEvent { 137 | /** 138 | * The type of element that emitted this event. 139 | */ 140 | elementType: 'linkAuthentication'; 141 | 142 | /** 143 | * Whether or not the LinkAuthentication Element is currently empty. 144 | */ 145 | empty: boolean; 146 | 147 | /** 148 | * Whether or not the LinkAuthentication Element is complete. 149 | */ 150 | complete: boolean; 151 | 152 | /** 153 | * An object containing the current email. 154 | */ 155 | value: { 156 | email: string; 157 | }; 158 | } 159 | -------------------------------------------------------------------------------- /types/stripe-js/elements/payment-request-button.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase, StripeElementClasses} from './base'; 2 | import {PaymentRequest} from '../payment-request'; 3 | import {Omit} from '../../utils'; 4 | 5 | export type StripePaymentRequestButtonElement = StripeElementBase & { 6 | /** 7 | * Triggered when the payment request button is clicked. 8 | */ 9 | on( 10 | eventType: 'click', 11 | handler: (event: StripePaymentRequestButtonElementClickEvent) => any 12 | ): StripePaymentRequestButtonElement; 13 | once( 14 | eventType: 'click', 15 | handler: (event: StripePaymentRequestButtonElementClickEvent) => any 16 | ): StripePaymentRequestButtonElement; 17 | off( 18 | eventType: 'click', 19 | handler?: (event: StripePaymentRequestButtonElementClickEvent) => any 20 | ): StripePaymentRequestButtonElement; 21 | 22 | /** 23 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 24 | */ 25 | on( 26 | eventType: 'ready', 27 | handler: (event: {elementType: 'paymentRequestButton'}) => any 28 | ): StripePaymentRequestButtonElement; 29 | once( 30 | eventType: 'ready', 31 | handler: (event: {elementType: 'paymentRequestButton'}) => any 32 | ): StripePaymentRequestButtonElement; 33 | off( 34 | eventType: 'ready', 35 | handler?: (event: {elementType: 'paymentRequestButton'}) => any 36 | ): StripePaymentRequestButtonElement; 37 | 38 | /** 39 | * Triggered when the element gains focus. 40 | */ 41 | on( 42 | eventType: 'focus', 43 | handler: (event: {elementType: 'paymentRequestButton'}) => any 44 | ): StripePaymentRequestButtonElement; 45 | once( 46 | eventType: 'focus', 47 | handler: (event: {elementType: 'paymentRequestButton'}) => any 48 | ): StripePaymentRequestButtonElement; 49 | off( 50 | eventType: 'focus', 51 | handler?: (event: {elementType: 'paymentRequestButton'}) => any 52 | ): StripePaymentRequestButtonElement; 53 | 54 | /** 55 | * Triggered when the element loses focus. 56 | */ 57 | on( 58 | eventType: 'blur', 59 | handler: (event: {elementType: 'paymentRequestButton'}) => any 60 | ): StripePaymentRequestButtonElement; 61 | once( 62 | eventType: 'blur', 63 | handler: (event: {elementType: 'paymentRequestButton'}) => any 64 | ): StripePaymentRequestButtonElement; 65 | off( 66 | eventType: 'blur', 67 | handler?: (event: {elementType: 'paymentRequestButton'}) => any 68 | ): StripePaymentRequestButtonElement; 69 | 70 | /** 71 | * Updates the options the `PaymentRequestButtonElement` was initialized with. 72 | * Updates are merged into the existing configuration. 73 | * 74 | * The styles of an `PaymentRequestButtonElement` can be dynamically changed using `element.update`. 75 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 76 | */ 77 | update( 78 | options: Partial< 79 | Omit 80 | > 81 | ): void; 82 | }; 83 | 84 | export interface StripePaymentRequestButtonElementOptions { 85 | classes?: StripeElementClasses; 86 | 87 | /** 88 | * An object used to customize the appearance of the Payment Request Button. 89 | * The object must have a single `paymentRequestButton` field, containing any of the following sub-fields 90 | */ 91 | style?: { 92 | paymentRequestButton: { 93 | /** 94 | * Preferred button type to display. Available types, by wallet: 95 | * 96 | * Browser card: default, book, buy, or donate. 97 | * 98 | * Google Pay: default, buy, or donate. 99 | * 100 | * Apple Pay: default, book, buy, donate, check-out, subscribe, reload, add-money, top-up, order, rent, support, contribute, tip 101 | * 102 | * When a wallet does not support the provided value, default is used as a fallback. 103 | */ 104 | type?: 105 | | 'default' 106 | | 'book' 107 | | 'buy' 108 | | 'donate' 109 | | 'check-out' 110 | | 'subscribe' 111 | | 'reload' 112 | | 'add-money' 113 | | 'top-up' 114 | | 'order' 115 | | 'rent' 116 | | 'support' 117 | | 'contribute' 118 | | 'tip'; 119 | 120 | /** 121 | * One of dark, light, or light-outline. The default is dark. 122 | */ 123 | theme?: 'dark' | 'light' | 'light-outline'; 124 | 125 | /** 126 | * The height of the Payment Request Button. Accepts px unit values. 127 | */ 128 | height?: string; 129 | 130 | /** 131 | * The gap between buttons when multile buttons are shown. Accepts px unit values. 132 | */ 133 | buttonSpacing?: string; 134 | }; 135 | }; 136 | 137 | /** 138 | * A `PaymentRequest` object used to configure the element. 139 | */ 140 | paymentRequest: PaymentRequest; 141 | 142 | /** 143 | * Disable showing multiple buttons. 144 | * Default is `false`. 145 | */ 146 | disableMultipleButtons?: boolean; 147 | } 148 | 149 | export interface StripePaymentRequestButtonElementClickEvent { 150 | preventDefault: () => void; 151 | } 152 | -------------------------------------------------------------------------------- /src/pure.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/no-var-requires */ 2 | import {RELEASE_TRAIN} from './shared'; 3 | 4 | const SCRIPT_SRC = `https://js.stripe.com/${RELEASE_TRAIN}/stripe.js`; 5 | const SCRIPT_SELECTOR = `script[src^="${SCRIPT_SRC}"]`; 6 | 7 | describe('pure module', () => { 8 | beforeEach(() => { 9 | jest.spyOn(console, 'warn').mockReturnValue(); 10 | }); 11 | 12 | afterEach(() => { 13 | const scripts = Array.from(document.querySelectorAll(SCRIPT_SELECTOR)); 14 | 15 | for (const script of scripts) { 16 | if (script.parentElement) { 17 | script.parentElement.removeChild(script); 18 | } 19 | } 20 | 21 | delete window.Stripe; 22 | 23 | jest.resetModules(); 24 | jest.restoreAllMocks(); 25 | }); 26 | 27 | test('does not inject the script if loadStripe is not called', async () => { 28 | require('./pure'); 29 | 30 | expect(document.querySelector(SCRIPT_SELECTOR)).toBe(null); 31 | }); 32 | 33 | test('it injects the script if loadStripe is called', async () => { 34 | const {loadStripe} = require('./pure'); 35 | loadStripe('pk_test_foo'); 36 | 37 | expect(document.querySelector(SCRIPT_SELECTOR)).not.toBe(null); 38 | }); 39 | 40 | test('it can load the script with advanced fraud signals disabled', () => { 41 | const {loadStripe} = require('./pure'); 42 | 43 | loadStripe.setLoadParameters({advancedFraudSignals: false}); 44 | loadStripe('pk_test_foo'); 45 | 46 | expect( 47 | document.querySelector( 48 | `script[src^="${SCRIPT_SRC}?advancedFraudSignals=false"]` 49 | ) 50 | ).not.toBe(null); 51 | }); 52 | 53 | test('it should throw when setting invalid load parameters', () => { 54 | const {loadStripe} = require('./pure'); 55 | 56 | expect(() => { 57 | loadStripe.setLoadParameters({howdy: true}); 58 | }).toThrow('invalid load parameters'); 59 | }); 60 | 61 | test('it should warn when calling loadStripe if a script already exists when parameters are set', () => { 62 | const script = document.createElement('script'); 63 | script.src = SCRIPT_SRC; 64 | document.body.appendChild(script); 65 | 66 | const {loadStripe} = require('./pure'); 67 | loadStripe.setLoadParameters({advancedFraudSignals: true}); 68 | loadStripe('pk_test_123'); 69 | 70 | expect(console.warn).toHaveBeenCalledTimes(1); 71 | expect(console.warn).toHaveBeenLastCalledWith( 72 | 'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used' 73 | ); 74 | }); 75 | 76 | test('it should warn when calling loadStripe if a script is added after parameters are set', () => { 77 | const {loadStripe} = require('./pure'); 78 | loadStripe.setLoadParameters({advancedFraudSignals: true}); 79 | 80 | const script = document.createElement('script'); 81 | script.src = SCRIPT_SRC; 82 | document.body.appendChild(script); 83 | 84 | loadStripe('pk_test_123'); 85 | 86 | expect(console.warn).toHaveBeenCalledTimes(1); 87 | expect(console.warn).toHaveBeenLastCalledWith( 88 | 'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used' 89 | ); 90 | }); 91 | 92 | test('it should warn when window.Stripe already exists if parameters are set', () => { 93 | window.Stripe = jest.fn((key) => ({key})) as any; 94 | 95 | const {loadStripe} = require('./pure'); 96 | loadStripe.setLoadParameters({advancedFraudSignals: true}); 97 | loadStripe('pk_test_123'); 98 | 99 | expect(console.warn).toHaveBeenCalledTimes(1); 100 | expect(console.warn).toHaveBeenLastCalledWith( 101 | 'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used' 102 | ); 103 | }); 104 | 105 | test('it should not warn when a script already exists if parameters are not set', () => { 106 | const script = document.createElement('script'); 107 | script.src = SCRIPT_SRC; 108 | document.body.appendChild(script); 109 | 110 | const {loadStripe} = require('./pure'); 111 | loadStripe('pk_test_123'); 112 | 113 | expect(console.warn).toHaveBeenCalledTimes(0); 114 | }); 115 | 116 | test('it should not warn when window.Stripe already exists if parameters are not set', () => { 117 | window.Stripe = jest.fn((key) => ({key})) as any; 118 | 119 | const {loadStripe} = require('./pure'); 120 | loadStripe('pk_test_123'); 121 | 122 | expect(console.warn).toHaveBeenCalledTimes(0); 123 | }); 124 | 125 | test('throws an error if calling setLoadParameters after loadStripe', () => { 126 | const {loadStripe} = require('./pure'); 127 | 128 | loadStripe.setLoadParameters({advancedFraudSignals: false}); 129 | loadStripe('pk_foo'); 130 | 131 | expect(() => { 132 | loadStripe.setLoadParameters({advancedFraudSignals: true}); 133 | }).toThrow('cannot change load parameters'); 134 | }); 135 | 136 | test('does not throw an error if calling setLoadParameters after loadStripe but the parameters are the same', () => { 137 | const {loadStripe} = require('./pure'); 138 | 139 | loadStripe.setLoadParameters({advancedFraudSignals: false}); 140 | loadStripe('pk_foo'); 141 | 142 | expect(() => { 143 | loadStripe.setLoadParameters({advancedFraudSignals: false}); 144 | }).not.toThrow('cannot change load parameters'); 145 | }); 146 | }); 147 | -------------------------------------------------------------------------------- /types/stripe-js/elements/shipping-address.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase} from './base'; 2 | import {StripeError} from '../stripe'; 3 | 4 | export type StripeShippingAddressElement = StripeElementBase & { 5 | /** 6 | * The change event is triggered when the `Element`'s value changes. 7 | */ 8 | on( 9 | eventType: 'change', 10 | handler: (event: StripeShippingAddressElementChangeEvent) => any 11 | ): StripeShippingAddressElement; 12 | once( 13 | eventType: 'change', 14 | handler: (event: StripeShippingAddressElementChangeEvent) => any 15 | ): StripeShippingAddressElement; 16 | off( 17 | eventType: 'change', 18 | handler?: (event: StripeShippingAddressElementChangeEvent) => any 19 | ): StripeShippingAddressElement; 20 | 21 | /** 22 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 23 | */ 24 | on( 25 | eventType: 'ready', 26 | handler: (event: {elementType: 'shippingAddress'}) => any 27 | ): StripeShippingAddressElement; 28 | once( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'shippingAddress'}) => any 31 | ): StripeShippingAddressElement; 32 | off( 33 | eventType: 'ready', 34 | handler?: (event: {elementType: 'shippingAddress'}) => any 35 | ): StripeShippingAddressElement; 36 | 37 | /** 38 | * Triggered when the element gains focus. 39 | */ 40 | on( 41 | eventType: 'focus', 42 | handler: (event: {elementType: 'shippingAddress'}) => any 43 | ): StripeShippingAddressElement; 44 | once( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'shippingAddress'}) => any 47 | ): StripeShippingAddressElement; 48 | off( 49 | eventType: 'focus', 50 | handler?: (event: {elementType: 'shippingAddress'}) => any 51 | ): StripeShippingAddressElement; 52 | 53 | /** 54 | * Triggered when the element loses focus. 55 | */ 56 | on( 57 | eventType: 'blur', 58 | handler: (event: {elementType: 'shippingAddress'}) => any 59 | ): StripeShippingAddressElement; 60 | once( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'shippingAddress'}) => any 63 | ): StripeShippingAddressElement; 64 | off( 65 | eventType: 'blur', 66 | handler?: (event: {elementType: 'shippingAddress'}) => any 67 | ): StripeShippingAddressElement; 68 | 69 | /** 70 | * Triggered when the escape key is pressed within the element. 71 | */ 72 | on( 73 | eventType: 'escape', 74 | handler: (event: {elementType: 'shippingAddress'}) => any 75 | ): StripeShippingAddressElement; 76 | once( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'shippingAddress'}) => any 79 | ): StripeShippingAddressElement; 80 | off( 81 | eventType: 'escape', 82 | handler?: (event: {elementType: 'shippingAddress'}) => any 83 | ): StripeShippingAddressElement; 84 | 85 | /** 86 | * Triggered when the element fails to load. 87 | */ 88 | on( 89 | eventType: 'loaderror', 90 | handler: (event: { 91 | elementType: 'shippingAddress'; 92 | error: StripeError; 93 | }) => any 94 | ): StripeShippingAddressElement; 95 | once( 96 | eventType: 'loaderror', 97 | handler: (event: { 98 | elementType: 'shippingAddress'; 99 | error: StripeError; 100 | }) => any 101 | ): StripeShippingAddressElement; 102 | off( 103 | eventType: 'loaderror', 104 | handler?: (event: { 105 | elementType: 'shippingAddress'; 106 | error: StripeError; 107 | }) => any 108 | ): StripeShippingAddressElement; 109 | 110 | /** 111 | * Triggered when the loader UI is mounted to the DOM and ready to be displayed. 112 | */ 113 | on( 114 | eventType: 'loaderstart', 115 | handler: (event: {elementType: 'shippingAddress'}) => any 116 | ): StripeShippingAddressElement; 117 | once( 118 | eventType: 'loaderstart', 119 | handler: (event: {elementType: 'shippingAddress'}) => any 120 | ): StripeShippingAddressElement; 121 | off( 122 | eventType: 'loaderstart', 123 | handler?: (event: {elementType: 'shippingAddress'}) => any 124 | ): StripeShippingAddressElement; 125 | 126 | /** 127 | * Updates the options the `ShippingAddressElement` was initialized with. 128 | * Updates are merged into the existing configuration. 129 | */ 130 | update( 131 | options: Partial 132 | ): StripeShippingAddressElement; 133 | }; 134 | 135 | export interface StripeShippingAddressElementOptions { 136 | /** 137 | * Control which countries are displayed in the shippingAddress Element. 138 | */ 139 | allowedCountries?: string[] | null; 140 | 141 | /** 142 | * Whether or not ShippingAddressElement accepts PO boxes 143 | */ 144 | blockPoBox?: boolean; 145 | 146 | /** 147 | * Default value for ShippingAddressElement fields 148 | */ 149 | defaultValues?: { 150 | name?: string | null; 151 | address?: { 152 | line1?: string | null; 153 | line2?: string | null; 154 | city?: string | null; 155 | state?: string | null; 156 | postal_code?: string | null; 157 | country: string; 158 | }; 159 | phone?: string | null; 160 | }; 161 | 162 | /** 163 | * Control which additional fields to display in the shippingAddress Element. 164 | */ 165 | fields?: { 166 | phone?: 'always' | 'never' | 'auto'; 167 | }; 168 | 169 | /** 170 | * Specify validation rules for the above additional fields. 171 | */ 172 | validation?: { 173 | phone?: { 174 | required: 'always' | 'never' | 'auto'; 175 | }; 176 | }; 177 | } 178 | 179 | export interface StripeShippingAddressElementChangeEvent { 180 | /** 181 | * The type of element that emitted this event. 182 | */ 183 | elementType: 'shippingAddress'; 184 | 185 | /** 186 | * Whether or not the shippingAddress Element is currently empty. 187 | */ 188 | empty: boolean; 189 | 190 | /** 191 | * Whether or not the shippingAddress Element is complete. 192 | */ 193 | complete: boolean; 194 | 195 | /** 196 | * Whether or not the shipping address is new. 197 | */ 198 | isNewAddress: boolean; 199 | 200 | /** 201 | * An object containing the current address. 202 | */ 203 | value: { 204 | name: string; 205 | address: { 206 | line1: string; 207 | line2: string | null; 208 | city: string; 209 | state: string; 210 | postal_code: string; 211 | country: string; 212 | }; 213 | phone?: string; 214 | }; 215 | } 216 | -------------------------------------------------------------------------------- /types/api/financial-connections.d.ts: -------------------------------------------------------------------------------- 1 | type SupportedPaymentMethodType = 'us_bank_account' | 'link'; 2 | 3 | interface CommonBalance { 4 | /** 5 | * The time that the external institution calculated this balance. Measured 6 | * in seconds since the Unix epoch. 7 | */ 8 | as_of: number; 9 | 10 | /** 11 | * The balances owed to (or by) the account holder. 12 | * 13 | * Each key is a three-letter ISO currency code, in lowercase. 14 | * 15 | * Each value is a integer amount. A positive amount indicates money owed to 16 | * the account holder. A negative amount indicates money owed by the account 17 | * holder. 18 | */ 19 | current: { 20 | [key: string]: number | undefined; 21 | }; 22 | } 23 | 24 | interface CashBalance { 25 | /** 26 | * Information on a `cash` balance. Only set if `balance.type` is `cash`. 27 | */ 28 | cash: { 29 | /** 30 | * The funds available to the account holder. Typically this is the 31 | * current balance less any holds. 32 | * 33 | * Each key is a three-letter ISO currency code, in lowercase. 34 | * 35 | * Each value is a integer amount. A positive amount indicates money owed 36 | * to the account holder. A negative amount indicates money owed by the 37 | * account holder. 38 | */ 39 | available: {[key: string]: number | undefined}; 40 | }; 41 | 42 | type: 'cash'; 43 | } 44 | 45 | interface CreditBalance { 46 | /** 47 | * Information on a `credit` balance. Only set if `balance.type` is `credit`. 48 | */ 49 | credit: { 50 | /** 51 | * The credit that has been used by the account holder. 52 | * 53 | * Each key is a three-letter ISO currency code, in lowercase 54 | * 55 | * Each value is a integer amount. A positive amount indicates money owed 56 | * to the account holder. A negative amount indicates money owed by the 57 | * account holder. 58 | */ 59 | used: {[key: string]: number | undefined}; 60 | }; 61 | 62 | type: 'credit'; 63 | } 64 | 65 | type Balance = (CommonBalance & CashBalance) | (CommonBalance & CreditBalance); 66 | 67 | interface BalanceRefresh { 68 | /** 69 | * The status of the Balance Refresh 70 | */ 71 | status: 'pending' | 'succeeded' | 'failed'; 72 | 73 | /** 74 | * Time at which the Balance Refresh was attempted. Measured in seconds since the Unix epoch. 75 | */ 76 | last_attempted_at: number; 77 | } 78 | 79 | interface OwnershipRefresh { 80 | /** 81 | * The status of the Ownership Refresh 82 | */ 83 | status: 'pending' | 'succeeded' | 'failed'; 84 | 85 | /** 86 | * Time at which the Ownersip Refresh was attempted. Measured in seconds since the Unix epoch. 87 | */ 88 | last_attempted_at: number; 89 | } 90 | 91 | /** 92 | * The Financial Connections Session object 93 | */ 94 | export interface FinancialConnectionsSession { 95 | /** 96 | * Unique identifier for the object. 97 | */ 98 | id: string; 99 | 100 | /** 101 | * List of accounts collected by the Session 102 | */ 103 | accounts: FinancialConnectionsSession.Account[]; 104 | 105 | /** 106 | * Filters applied to the Session 107 | */ 108 | filters?: FinancialConnectionsSession.Filters; 109 | 110 | /** 111 | * List of data permissions requested in the Session 112 | */ 113 | permissions?: FinancialConnectionsSession.Permission[]; 114 | 115 | /** 116 | * For webview integrations only. The user will be redirected to this URL to return to your app. 117 | */ 118 | return_url?: string; 119 | } 120 | 121 | export namespace FinancialConnectionsSession { 122 | /** 123 | * The Financial Connections Account object 124 | */ 125 | export interface Account { 126 | /** 127 | * Unique identifier for the object. 128 | */ 129 | id: string; 130 | 131 | /** 132 | * String representing the object's type. `'linked_account'` is present for backwards-compatibility. 133 | */ 134 | object: 'linked_account' | 'financial_connections.account'; 135 | 136 | /** 137 | * The balance for this Account 138 | */ 139 | balance: null | Balance; 140 | 141 | /** 142 | * The most recent Balance Refresh for this Account 143 | */ 144 | balance_refresh: null | BalanceRefresh; 145 | 146 | /** 147 | * The type of the account. 148 | */ 149 | category: 'cash' | 'credit' | 'investment' | 'other'; 150 | 151 | /** 152 | * Time at which the object was created. Measured in seconds since the Unix epoch. 153 | */ 154 | created: number; 155 | 156 | /** 157 | * A human-readable name that has been assigned to this account, either by the account holder or by the institution. 158 | */ 159 | display_name: string; 160 | 161 | /** 162 | * The name of the institution that holds this account. 163 | */ 164 | institution_name: string; 165 | 166 | /** 167 | * The last 4 digits of the account number. If present, this will be 4 numeric characters. 168 | */ 169 | last4: string | null; 170 | 171 | /** 172 | * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. 173 | */ 174 | livemode: boolean; 175 | 176 | /** 177 | * The ID of this account's Ownership resource. 178 | */ 179 | ownership: string | null; 180 | 181 | /** 182 | * The most recent Ownership Refresh for this Account 183 | */ 184 | ownership_refresh: null | OwnershipRefresh; 185 | 186 | /** 187 | * Permissions granted on this Account 188 | */ 189 | permissions: Permission[]; 190 | 191 | /** 192 | * The status of the Account 193 | */ 194 | status: 'active' | 'inactive' | 'disconnected'; 195 | 196 | /** 197 | * The sub-category of the Account 198 | */ 199 | subcategory: 200 | | 'checking' 201 | | 'savings' 202 | | 'mortgage' 203 | | 'line_of_credit' 204 | | 'credit_card' 205 | | 'other'; 206 | 207 | /** 208 | * The types of Payment Methods which can be set up by this Account 209 | */ 210 | supported_payment_method_types: SupportedPaymentMethodType[]; 211 | } 212 | 213 | /** 214 | * Filters to restrict the kinds of accounts to collect. 215 | */ 216 | export interface Filters { 217 | /** 218 | * List of countries from which to collect accounts. 219 | */ 220 | countries?: string[]; 221 | } 222 | 223 | /** 224 | * Data features to which access can be requested 225 | */ 226 | export type Permission = 227 | | 'payment_method' 228 | | 'balances' 229 | | 'transactions' 230 | | 'ownership' 231 | | 'account_numbers'; 232 | } 233 | -------------------------------------------------------------------------------- /types/api/confirmation-tokens.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElements} from '../stripe-js'; 2 | import {Address} from './shared'; 3 | import {PaymentMethod, PaymentMethodCreateParams} from './payment-methods'; 4 | import {PaymentIntent} from './payment-intents'; 5 | 6 | /** 7 | * The ConfirmationToken object. 8 | */ 9 | export interface ConfirmationToken { 10 | /** 11 | * Unique identifier for the object. 12 | */ 13 | id: string; 14 | 15 | /** 16 | * String representing the object's type. Objects of the same type share the same value. 17 | */ 18 | object: 'confirmation_token'; 19 | 20 | /** 21 | * Time at which the object was created. Measured in seconds since the Unix epoch. 22 | */ 23 | created: number; 24 | 25 | /** 26 | * Time at which this ConfirmationToken expires and can no longer be used to confirm a PaymentIntent or SetupIntent. This is set to null once this ConfirmationToken has been used. Measured in seconds since the Unix epoch. 27 | */ 28 | expires_at: number; 29 | 30 | /** 31 | * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. 32 | */ 33 | livemode: boolean; 34 | 35 | /** 36 | * ID of the PaymentIntent that this ConfirmationToken was used to confirm, or null if this ConfirmationToken has not yet been used. 37 | */ 38 | payment_intent: null | string; 39 | 40 | /** 41 | * Payment details collected by the Payment Element, used to create a PaymentMethod when a PaymentIntent or SetupIntent is confirmed with this ConfirmationToken. 42 | */ 43 | payment_method_preview: ConfirmationToken.PaymentMethodPreview; 44 | 45 | /** 46 | * The URL your customer is redirected to after they complete the payment. 47 | */ 48 | return_url: string | null; 49 | 50 | /** 51 | * Indicates that you intend to make future payments with this ConfirmationToken’s payment method. 52 | * 53 | * The presence of this property will [attach the payment method](https://stripe.com/docs/payments/save-during-payment) to the PaymentIntent’s Customer, if present, after the PaymentIntent is confirmed and any required actions from the user are complete. 54 | * 55 | * Stripe uses `setup_future_usage` to dynamically optimize your payment flow and comply with regional legislation and network rules. For example, if your customer is impacted by [SCA](https://stripe.com/docs/strong-customer-authentication), using `off_session` will ensure that they are authenticated while processing this PaymentIntent. You will then be able to collect [off-session payments](https://stripe.com/docs/payments/cards/charging-saved-cards#off-session-payments-with-saved-cards) for this customer. 56 | */ 57 | setup_future_usage: PaymentIntent.SetupFutureUsage | null; 58 | 59 | /** 60 | * ID of the SetupIntent that this ConfirmationToken was used to confirm, or null if this ConfirmationToken has not yet been used. 61 | */ 62 | setup_intent: null | string; 63 | 64 | /** 65 | * Shipping information for this ConfirmationToken. 66 | */ 67 | shipping: PaymentIntent.Shipping | null; 68 | 69 | /** 70 | * Set to true when confirming server-side and using Stripe.js, iOS, or Android client-side SDKs to handle the next actions. 71 | */ 72 | use_stripe_sdk: boolean; 73 | } 74 | 75 | export interface ConfirmationTokenCreateParams { 76 | /** 77 | * Data used to create a new payment method. 78 | * 79 | */ 80 | payment_method_data?: { 81 | /** 82 | * The customer's billing details. 83 | */ 84 | billing_details?: PaymentMethodCreateParams.BillingDetails; 85 | 86 | /** 87 | * Specifies if the PaymentMethod should be redisplayed when using the Saved Payment Method feature 88 | */ 89 | allow_redisplay?: 'always' | 'limited' | 'unspecified'; 90 | 91 | /** 92 | * Set of key-value pairs that you can attach to an object. This can be useful for storing additional information about the object in a structured format. 93 | * Individual keys can be unset by posting an empty value to them 94 | * @docs https://docs.stripe.com/metadata 95 | */ 96 | metadata?: Record; 97 | }; 98 | 99 | /** 100 | * Shipping information. 101 | */ 102 | shipping?: ConfirmationToken.Shipping; 103 | 104 | /** 105 | * The url your customer will be directed to after they complete authentication. 106 | */ 107 | return_url?: string | null; 108 | } 109 | 110 | export interface CreateConfirmationToken { 111 | /** 112 | * The Elements instance. 113 | * 114 | * @docs https://stripe.com/docs/js/elements_object 115 | */ 116 | elements: StripeElements; 117 | 118 | /** 119 | * Parameters for creating the ConfirmationToken. 120 | * Details collected by Elements will be overriden by values passed here. 121 | */ 122 | params?: ConfirmationTokenCreateParams; 123 | } 124 | 125 | export namespace ConfirmationToken { 126 | export interface Shipping { 127 | /** 128 | * Recipient address. 129 | */ 130 | address: Address; 131 | 132 | /** 133 | * Recipient name. 134 | */ 135 | name: string | null; 136 | 137 | /** 138 | * Recipient phone (including extension). 139 | */ 140 | phone?: string | null; 141 | } 142 | 143 | export interface PaymentMethodPreview { 144 | /** 145 | * The type of the PaymentMethod. An additional hash is included on payment_method_preview with a name matching this value. It contains additional information specific to the PaymentMethod type. 146 | */ 147 | type: string; 148 | 149 | billing_details: PaymentMethod.BillingDetails; 150 | 151 | acss_debit?: PaymentMethod.AcssDebit; 152 | 153 | affirm?: PaymentMethod.Affirm; 154 | 155 | afterpay_clearpay?: PaymentMethod.AfterpayClearpay; 156 | 157 | au_becs_debit?: PaymentMethod.AuBecsDebit; 158 | 159 | card?: PaymentMethod.Card; 160 | 161 | card_present?: PaymentMethod.CardPresent; 162 | 163 | eps?: PaymentMethod.Eps; 164 | 165 | fpx?: PaymentMethod.Fpx; 166 | 167 | grabpay?: PaymentMethod.GrabPay; 168 | 169 | ideal?: PaymentMethod.Ideal; 170 | 171 | p24?: PaymentMethod.P24; 172 | 173 | sepa_debit?: PaymentMethod.SepaDebit; 174 | 175 | us_bank_account?: PaymentMethod.UsBankAccount; 176 | } 177 | 178 | export interface MandateData { 179 | customer_acceptance: { 180 | type: 'online'; 181 | 182 | online?: { 183 | /** 184 | * The IP address from which the Mandate was accepted by the customer. 185 | */ 186 | ip_address: string; 187 | 188 | /** 189 | * The user agent of the browser from which the Mandate was accepted by the customer. 190 | */ 191 | user_agent: string; 192 | }; 193 | }; 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /types/stripe-js/elements/card-number.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | import {StripeError} from '../stripe'; 8 | import {CardNetworkBrand} from '../elements-group'; 9 | 10 | export type StripeCardNumberElement = StripeElementBase & { 11 | /** 12 | * The change event is triggered when the `Element`'s value changes. 13 | */ 14 | on( 15 | eventType: 'change', 16 | handler: (event: StripeCardNumberElementChangeEvent) => any 17 | ): StripeCardNumberElement; 18 | once( 19 | eventType: 'change', 20 | handler: (event: StripeCardNumberElementChangeEvent) => any 21 | ): StripeCardNumberElement; 22 | off( 23 | eventType: 'change', 24 | handler?: (event: StripeCardNumberElementChangeEvent) => any 25 | ): StripeCardNumberElement; 26 | 27 | /** 28 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 29 | */ 30 | on( 31 | eventType: 'ready', 32 | handler: (event: {elementType: 'cardNumber'}) => any 33 | ): StripeCardNumberElement; 34 | once( 35 | eventType: 'ready', 36 | handler: (event: {elementType: 'cardNumber'}) => any 37 | ): StripeCardNumberElement; 38 | off( 39 | eventType: 'ready', 40 | handler?: (event: {elementType: 'cardNumber'}) => any 41 | ): StripeCardNumberElement; 42 | 43 | /** 44 | * Triggered when the element gains focus. 45 | */ 46 | on( 47 | eventType: 'focus', 48 | handler: (event: {elementType: 'cardNumber'}) => any 49 | ): StripeCardNumberElement; 50 | once( 51 | eventType: 'focus', 52 | handler: (event: {elementType: 'cardNumber'}) => any 53 | ): StripeCardNumberElement; 54 | off( 55 | eventType: 'focus', 56 | handler?: (event: {elementType: 'cardNumber'}) => any 57 | ): StripeCardNumberElement; 58 | 59 | /** 60 | * Triggered when the element loses focus. 61 | */ 62 | on( 63 | eventType: 'blur', 64 | handler: (event: {elementType: 'cardNumber'}) => any 65 | ): StripeCardNumberElement; 66 | once( 67 | eventType: 'blur', 68 | handler: (event: {elementType: 'cardNumber'}) => any 69 | ): StripeCardNumberElement; 70 | off( 71 | eventType: 'blur', 72 | handler?: (event: {elementType: 'cardNumber'}) => any 73 | ): StripeCardNumberElement; 74 | 75 | /** 76 | * Triggered when the escape key is pressed within the element. 77 | */ 78 | on( 79 | eventType: 'escape', 80 | handler: (event: {elementType: 'cardNumber'}) => any 81 | ): StripeCardNumberElement; 82 | once( 83 | eventType: 'escape', 84 | handler: (event: {elementType: 'cardNumber'}) => any 85 | ): StripeCardNumberElement; 86 | off( 87 | eventType: 'escape', 88 | handler?: (event: {elementType: 'cardNumber'}) => any 89 | ): StripeCardNumberElement; 90 | 91 | /** 92 | * Triggered when there is a change to the available networks the provided card can run on. 93 | */ 94 | on( 95 | eventType: 'networkschange', 96 | handler: (event: {elementType: 'cardNumber'}) => any 97 | ): StripeCardNumberElement; 98 | once( 99 | eventType: 'networkschange', 100 | handler: (event: {elementType: 'cardNumber'}) => any 101 | ): StripeCardNumberElement; 102 | off( 103 | eventType: 'networkschange', 104 | handler?: (event: {elementType: 'cardNumber'}) => any 105 | ): StripeCardNumberElement; 106 | 107 | /** 108 | * Triggered when the element fails to load. 109 | */ 110 | on( 111 | eventType: 'loaderror', 112 | handler: (event: {elementType: 'cardNumber'; error: StripeError}) => any 113 | ): StripeCardNumberElement; 114 | once( 115 | eventType: 'loaderror', 116 | handler: (event: {elementType: 'cardNumber'; error: StripeError}) => any 117 | ): StripeCardNumberElement; 118 | off( 119 | eventType: 'loaderror', 120 | handler?: (event: {elementType: 'cardNumber'; error: StripeError}) => any 121 | ): StripeCardNumberElement; 122 | 123 | /** 124 | * Updates the options the `CardNumberElement` was initialized with. 125 | * Updates are merged into the existing configuration. 126 | * 127 | * The styles of an `Element` can be dynamically changed using `element.update`. 128 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 129 | */ 130 | update(options: Partial): void; 131 | }; 132 | 133 | export interface StripeCardNumberElementOptions { 134 | classes?: StripeElementClasses; 135 | 136 | style?: StripeElementStyle; 137 | 138 | placeholder?: string; 139 | 140 | /** 141 | * Applies a disabled state to the Element such that user input is not accepted. 142 | * Default is `false`. 143 | */ 144 | disabled?: boolean; 145 | 146 | /** 147 | * Show a card brand icon in the Element. 148 | * Default is `false`. 149 | */ 150 | showIcon?: boolean; 151 | 152 | /** 153 | * Appearance of the brand icon in the Element. 154 | */ 155 | iconStyle?: 'default' | 'solid'; 156 | 157 | /** 158 | * Hides and disables the Link Button in the Card Element. 159 | * Default is `false`. 160 | */ 161 | disableLink?: boolean; 162 | 163 | /** 164 | * Specifies a network preference for Card Brand Choice. The first network in the array which is a valid 165 | * network on the entered card will be selected as the default in the Card Brand Choice dropdown upon 166 | * entry of a co-branded card. 167 | * 168 | * Default is an empty array, meaning no default selection will be made in the Card Brand choice dropdown. 169 | */ 170 | preferredNetwork?: Array; 171 | } 172 | 173 | export interface StripeCardNumberElementUpdateOptions { 174 | classes?: StripeElementClasses; 175 | 176 | style?: StripeElementStyle; 177 | 178 | placeholder?: string; 179 | 180 | /** 181 | * Applies a disabled state to the Element such that user input is not accepted. 182 | * Default is `false`. 183 | */ 184 | disabled?: boolean; 185 | 186 | /** 187 | * Show a card brand icon in the Element. 188 | * Default is `false`. 189 | */ 190 | showIcon?: boolean; 191 | 192 | /** 193 | * Appearance of the brand icon in the Element. 194 | */ 195 | iconStyle?: 'default' | 'solid'; 196 | } 197 | 198 | export interface StripeCardNumberElementChangeEvent 199 | extends StripeElementChangeEvent { 200 | /** 201 | * The type of element that emitted this event. 202 | */ 203 | elementType: 'cardNumber'; 204 | 205 | /* 206 | * The card brand of the card number being entered. 207 | */ 208 | brand: 209 | | 'visa' 210 | | 'mastercard' 211 | | 'amex' 212 | | 'discover' 213 | | 'diners' 214 | | 'jcb' 215 | | 'unionpay' 216 | | 'unknown'; 217 | } 218 | -------------------------------------------------------------------------------- /src/shared.ts: -------------------------------------------------------------------------------- 1 | import {Stripe, StripeConstructor} from '../types'; 2 | 3 | export type LoadStripe = ( 4 | ...args: Parameters 5 | ) => Promise; 6 | 7 | export interface LoadParams { 8 | advancedFraudSignals: boolean; 9 | } 10 | 11 | // `_VERSION` will be rewritten by `@rollup/plugin-replace` as a string literal 12 | // containing the package.json version 13 | declare const _VERSION: string; 14 | 15 | export const RELEASE_TRAIN = 'clover'; 16 | 17 | const runtimeVersionToUrlVersion = (version: string | number) => 18 | version === 3 ? 'v3' : version; 19 | 20 | const ORIGIN = 'https://js.stripe.com'; 21 | const STRIPE_JS_URL = `${ORIGIN}/${RELEASE_TRAIN}/stripe.js`; 22 | 23 | const V3_URL_REGEX = /^https:\/\/js\.stripe\.com\/v3\/?(\?.*)?$/; 24 | const STRIPE_JS_URL_REGEX = /^https:\/\/js\.stripe\.com\/(v3|[a-z]+)\/stripe\.js(\?.*)?$/; 25 | const EXISTING_SCRIPT_MESSAGE = 26 | 'loadStripe.setLoadParameters was called but an existing Stripe.js script already exists in the document; existing script parameters will be used'; 27 | 28 | const isStripeJSURL = (url: string): boolean => 29 | V3_URL_REGEX.test(url) || STRIPE_JS_URL_REGEX.test(url); 30 | 31 | export const findScript = (): HTMLScriptElement | null => { 32 | const scripts = document.querySelectorAll( 33 | `script[src^="${ORIGIN}"]` 34 | ); 35 | 36 | for (let i = 0; i < scripts.length; i++) { 37 | const script = scripts[i]; 38 | 39 | if (!isStripeJSURL(script.src)) { 40 | continue; 41 | } 42 | 43 | return script; 44 | } 45 | 46 | return null; 47 | }; 48 | 49 | const injectScript = (params: null | LoadParams): HTMLScriptElement => { 50 | const queryString = 51 | params && !params.advancedFraudSignals ? '?advancedFraudSignals=false' : ''; 52 | const script = document.createElement('script'); 53 | script.src = `${STRIPE_JS_URL}${queryString}`; 54 | 55 | const headOrBody = document.head || document.body; 56 | 57 | if (!headOrBody) { 58 | throw new Error( 59 | 'Expected document.body not to be null. Stripe.js requires a element.' 60 | ); 61 | } 62 | 63 | headOrBody.appendChild(script); 64 | 65 | return script; 66 | }; 67 | 68 | const registerWrapper = (stripe: any, startTime: number): void => { 69 | if (!stripe || !stripe._registerWrapper) { 70 | return; 71 | } 72 | 73 | stripe._registerWrapper({name: 'stripe-js', version: _VERSION, startTime}); 74 | }; 75 | 76 | let stripePromise: Promise | null = null; 77 | 78 | let onErrorListener: ((cause?: unknown) => void) | null = null; 79 | let onLoadListener: (() => void) | null = null; 80 | 81 | const onError = (reject: (reason?: any) => void) => (cause?: unknown) => { 82 | reject(new Error('Failed to load Stripe.js', {cause})); 83 | }; 84 | 85 | const onLoad = ( 86 | resolve: ( 87 | value: StripeConstructor | PromiseLike | null 88 | ) => void, 89 | reject: (reason?: any) => void 90 | ) => () => { 91 | if (window.Stripe) { 92 | resolve(window.Stripe); 93 | } else { 94 | reject(new Error('Stripe.js not available')); 95 | } 96 | }; 97 | 98 | export const loadScript = ( 99 | params: null | LoadParams 100 | ): Promise => { 101 | // Ensure that we only attempt to load Stripe.js at most once 102 | if (stripePromise !== null) { 103 | return stripePromise; 104 | } 105 | 106 | stripePromise = new Promise((resolve, reject) => { 107 | if (typeof window === 'undefined' || typeof document === 'undefined') { 108 | // Resolve to null when imported server side. This makes the module 109 | // safe to import in an isomorphic code base. 110 | resolve(null); 111 | return; 112 | } 113 | 114 | if (window.Stripe && params) { 115 | console.warn(EXISTING_SCRIPT_MESSAGE); 116 | } 117 | 118 | if (window.Stripe) { 119 | resolve(window.Stripe); 120 | return; 121 | } 122 | 123 | try { 124 | let script = findScript(); 125 | 126 | if (script && params) { 127 | console.warn(EXISTING_SCRIPT_MESSAGE); 128 | } else if (!script) { 129 | script = injectScript(params); 130 | } else if ( 131 | script && 132 | onLoadListener !== null && 133 | onErrorListener !== null 134 | ) { 135 | // remove event listeners 136 | script.removeEventListener('load', onLoadListener); 137 | script.removeEventListener('error', onErrorListener); 138 | 139 | // if script exists, but we are reloading due to an error, 140 | // reload script to trigger 'load' event 141 | script.parentNode?.removeChild(script); 142 | script = injectScript(params); 143 | } 144 | 145 | onLoadListener = onLoad(resolve, reject); 146 | onErrorListener = onError(reject); 147 | script.addEventListener('load', onLoadListener); 148 | 149 | script.addEventListener('error', onErrorListener); 150 | } catch (error) { 151 | reject(error); 152 | return; 153 | } 154 | }); 155 | // Resets stripePromise on error 156 | return stripePromise.catch((error) => { 157 | stripePromise = null; 158 | return Promise.reject(error); 159 | }); 160 | }; 161 | 162 | export const initStripe = ( 163 | maybeStripe: StripeConstructor | null, 164 | args: Parameters, 165 | startTime: number 166 | ): Stripe | null => { 167 | if (maybeStripe === null) { 168 | return null; 169 | } 170 | 171 | const pk = args[0]; 172 | const isTestKey = pk.match(/^pk_test/); 173 | 174 | // @ts-expect-error this is not publicly typed 175 | const version = runtimeVersionToUrlVersion(maybeStripe.version); 176 | const expectedVersion = RELEASE_TRAIN; 177 | if (isTestKey && version !== expectedVersion) { 178 | console.warn( 179 | `Stripe.js@${version} was loaded on the page, but @stripe/stripe-js@${_VERSION} expected Stripe.js@${expectedVersion}. This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning` 180 | ); 181 | } 182 | 183 | const stripe = maybeStripe.apply(undefined, args); 184 | registerWrapper(stripe, startTime); 185 | return stripe; 186 | }; 187 | 188 | // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types 189 | export const validateLoadParams = (params: any): LoadParams => { 190 | const errorMessage = `invalid load parameters; expected object of shape 191 | 192 | {advancedFraudSignals: boolean} 193 | 194 | but received 195 | 196 | ${JSON.stringify(params)} 197 | `; 198 | 199 | if (params === null || typeof params !== 'object') { 200 | throw new Error(errorMessage); 201 | } 202 | 203 | if ( 204 | Object.keys(params).length === 1 && 205 | typeof params.advancedFraudSignals === 'boolean' 206 | ) { 207 | return params; 208 | } 209 | 210 | throw new Error(errorMessage); 211 | }; 212 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stripe.js as a CommonJS module or ES module 2 | 3 | This package allows [Stripe.js](https://stripe.com/docs/stripe-js) to be 4 | imported as a CommonJS module or ES module. 5 | 6 | **Note**: To be 7 | [PCI compliant](https://stripe.com/docs/security/guide#validating-pci-compliance), 8 | you must load Stripe.js directly from `https://js.stripe.com`. You cannot 9 | include it in a bundle or host it yourself. This package wraps the global 10 | `Stripe` function provided by the Stripe.js script as an ES module. 11 | 12 | Calling `loadStripe` always loads the latest version of Stripe.js, regardless of 13 | which version of `@stripe/stripe-js` you use. Updates for this package only 14 | impact tooling around the `loadStripe` helper itself and the TypeScript type 15 | definitions provided for Stripe.js. Updates do not affect runtime availability 16 | of features of Stripe.js. 17 | 18 | [![npm version](https://img.shields.io/npm/v/@stripe/stripe-js.svg?style=flat-square)](https://www.npmjs.com/package/@stripe/stripe-js) 19 | 20 | ## Minimum requirements 21 | 22 | - Node.js: v12.16 23 | - TypeScript: v.3.1.1 24 | 25 | ## Installation 26 | 27 | Use `npm` to install the Stripe.js module: 28 | 29 | ```sh 30 | npm install @stripe/stripe-js 31 | ``` 32 | 33 | ## Versioning 34 | 35 | Each `@stripe/stripe-js` version is pinned to a specific 36 | [Stripe.js version](https://docs.stripe.com/sdks/stripejs-versioning). The 37 | pinned versions are as follows: 38 | 39 | | **@stripe/stripe-js** | **Stripe.js** | 40 | | --------------------- | ------------- | 41 | | <6 | v3 | 42 | | v6 | acacia | 43 | | v7 | basil | 44 | | v8 | clover | 45 | 46 | ## Usage 47 | 48 | ### `loadStripe` 49 | 50 | This function returns a `Promise` that resolves with a newly created `Stripe` 51 | object once Stripe.js has loaded. It takes the same parameters passed when 52 | directly 53 | [initializing a `Stripe` instance](https://stripe.com/docs/js/initializing). If 54 | necessary, it will load Stripe.js for you by inserting the Stripe.js script tag. 55 | If you call `loadStripe` in a server environment it will resolve to `null`. 56 | 57 | ```js 58 | import {loadStripe} from '@stripe/stripe-js'; 59 | 60 | const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); 61 | ``` 62 | 63 | We’ve placed a random API key in this example. Replace it with your 64 | [actual publishable API keys](https://dashboard.stripe.com/account/apikeys) to 65 | test this code through your Stripe account. 66 | 67 | For more information on how to use Stripe.js, please refer to the 68 | [Stripe.js API reference](https://stripe.com/docs/js) or learn to 69 | [accept a payment](https://stripe.com/docs/payments/accept-a-payment) with 70 | Stripe. 71 | 72 | If you have deployed a 73 | [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP), 74 | make sure to 75 | [include Stripe.js in your directives](https://stripe.com/docs/security/guide#content-security-policy). 76 | 77 | ## TypeScript support 78 | 79 | This package includes TypeScript declarations for Stripe.js. We support projects 80 | using TypeScript versions >= 3.1. 81 | 82 | Some methods in Stripe.js accept and return objects from the 83 | [Stripe API](https://stripe.com/docs/api). The type declarations in 84 | `@stripe/stripe-js` for these objects in will always track the 85 | [latest version](https://stripe.com/docs/api/versioning) of the Stripe API. If 86 | you would like to use these types but are using an older version of the Stripe 87 | API, we recommend 88 | [updating to the latest version](https://stripe.com/docs/upgrades#how-can-i-upgrade-my-api), 89 | or ignoring and overriding the type definitions as necessary. 90 | 91 | Note that we may release new [minor and patch](https://semver.org/) versions of 92 | `@stripe/stripe-js` with small but backwards-incompatible fixes to the type 93 | declarations. These changes will not affect Stripe.js itself. 94 | 95 | ## Ensuring Stripe.js is available everywhere 96 | 97 | To best leverage Stripe’s advanced fraud functionality, ensure that Stripe.js is 98 | loaded on every page, not just your checkout page. This 99 | [allows Stripe to detect suspicious behavior](https://stripe.com/docs/disputes/prevention/advanced-fraud-detection) 100 | that may be indicative of fraud as customers browse your website. 101 | 102 | By default, this module will insert a ` 128 | ``` 129 | 130 | ### Importing `loadStripe` without side effects 131 | 132 | If you would like to use `loadStripe` in your application, but defer loading the 133 | Stripe.js script until `loadStripe` is first called, use the alternative 134 | `@stripe/stripe-js/pure` import module: 135 | 136 | ```js 137 | // CommonJS module import 138 | const {loadStripe} = require('@stripe/stripe-js/pure'); 139 | // ES module import 140 | import {loadStripe} from '@stripe/stripe-js/pure'; 141 | 142 | // Stripe.js will not be loaded until `loadStripe` is called 143 | const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); 144 | ``` 145 | 146 | ### Disabling advanced fraud detection signals 147 | 148 | If you would like to 149 | [disable advanced fraud detection](https://stripe.com/docs/disputes/prevention/advanced-fraud-detection#disabling-advanced-fraud-detection) 150 | altogether, use `loadStripe.setLoadParameters`: 151 | 152 | ```js 153 | // CommonJS module import 154 | const {loadStripe} = require('@stripe/stripe-js/pure'); 155 | // ES module import 156 | import {loadStripe} from '@stripe/stripe-js/pure'; 157 | 158 | loadStripe.setLoadParameters({advancedFraudSignals: false}); 159 | const stripe = await loadStripe('pk_test_TYooMQauvdEDq54NiTphI7jx'); 160 | ``` 161 | 162 | The `loadStripe.setLoadParameters` function is only available when importing 163 | `loadStripe` from `@stripe/stripe-js/pure`. 164 | 165 | ## Stripe.js Documentation 166 | 167 | - [Stripe.js Docs](https://stripe.com/docs/stripe-js) 168 | - [Stripe.js Reference](https://stripe.com/docs/js) 169 | - [React Stripe.js Docs](https://stripe.com/docs/stripe-js/react) 170 | -------------------------------------------------------------------------------- /src/index.test.ts: -------------------------------------------------------------------------------- 1 | import {SCRIPT_SRC} from './testUtils'; 2 | /* eslint-disable @typescript-eslint/no-var-requires */ 3 | 4 | const dispatchScriptEvent = (eventType: string): void => { 5 | const injectedScript = document.querySelector(`script[src="${SCRIPT_SRC}"]`); 6 | 7 | if (!injectedScript) { 8 | throw new Error('could not find Stripe.js script element'); 9 | } 10 | 11 | injectedScript.dispatchEvent(new Event(eventType)); 12 | }; 13 | 14 | describe('Stripe module loader', () => { 15 | afterEach(() => { 16 | const script = document.querySelector( 17 | 'script[src^="https://js.stripe.com/"]' 18 | ); 19 | if (script && script.parentElement) { 20 | script.parentElement.removeChild(script); 21 | } 22 | 23 | delete window.Stripe; 24 | jest.resetModules(); 25 | }); 26 | 27 | it('injects the Stripe script as a side effect after a tick', () => { 28 | require('./index'); 29 | 30 | expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).toBe(null); 31 | 32 | return Promise.resolve().then(() => { 33 | expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).not.toBe( 34 | null 35 | ); 36 | }); 37 | }); 38 | 39 | it('does not inject the script when Stripe is already loaded', () => { 40 | require('./index'); 41 | 42 | window.Stripe = jest.fn((key) => ({key})) as any; 43 | 44 | return new Promise((resolve) => setTimeout(resolve)).then(() => { 45 | expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).toBe(null); 46 | }); 47 | }); 48 | 49 | describe('does not inject a duplicate script when one is already present', () => { 50 | test('when the script has a trailing slash', () => { 51 | require('./index'); 52 | 53 | const script = document.createElement('script'); 54 | script.src = SCRIPT_SRC; 55 | document.body.appendChild(script); 56 | 57 | return Promise.resolve().then(() => { 58 | expect( 59 | document.querySelectorAll(`script[src="${SCRIPT_SRC}"]`) 60 | ).toHaveLength(1); 61 | }); 62 | }); 63 | 64 | test('ignores non-Stripe.js scripts that start with the v3 url', async () => { 65 | const script = document.createElement('script'); 66 | script.src = 'https://js.stripe.com/v3/futureBundle.js'; 67 | document.body.appendChild(script); 68 | 69 | require('./index'); 70 | 71 | await Promise.resolve(); 72 | 73 | expect( 74 | document.querySelectorAll('script[src^="https://js.stripe.com"]') 75 | ).toHaveLength(2); 76 | 77 | expect( 78 | document.querySelector( 79 | 'script[src="https://js.stripe.com/v3/futureBundle.js"]' 80 | ) 81 | ).not.toBe(null); 82 | 83 | expect(document.querySelector(`script[src="${SCRIPT_SRC}"]`)).not.toBe( 84 | null 85 | ); 86 | }); 87 | }); 88 | 89 | describe.each(['./index', './pure'])('loadStripe (%s.ts)', (requirePath) => { 90 | beforeEach(() => { 91 | jest.restoreAllMocks(); 92 | jest.spyOn(console, 'warn').mockReturnValue(); 93 | }); 94 | 95 | it('resolves loadStripe with Stripe object', async () => { 96 | const {loadStripe} = require(requirePath); 97 | const stripePromise = loadStripe('pk_test_foo'); 98 | 99 | await new Promise((resolve) => setTimeout(resolve)); 100 | window.Stripe = jest.fn((key) => ({key})) as any; 101 | dispatchScriptEvent('load'); 102 | 103 | return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'}); 104 | }); 105 | 106 | it('rejects when the script fails', async () => { 107 | const {loadStripe} = require(requirePath); 108 | const stripePromise = loadStripe('pk_test_foo'); 109 | 110 | await Promise.resolve(); 111 | dispatchScriptEvent('error'); 112 | 113 | await expect(stripePromise).rejects.toEqual( 114 | new Error('Failed to load Stripe.js') 115 | ); 116 | 117 | expect(console.warn).not.toHaveBeenCalled(); 118 | }); 119 | 120 | it('rejects when Stripe is not added to the window for some reason', async () => { 121 | const {loadStripe} = require(requirePath); 122 | const stripePromise = loadStripe('pk_test_foo'); 123 | 124 | await Promise.resolve(); 125 | dispatchScriptEvent('load'); 126 | 127 | return expect(stripePromise).rejects.toEqual( 128 | new Error('Stripe.js not available') 129 | ); 130 | }); 131 | 132 | it('rejects on first load, and succeeds on second load resolving with Stripe object', async () => { 133 | const {loadStripe} = require(requirePath); 134 | 135 | // start of first load, expect load failure 136 | let stripePromise = loadStripe('pk_test_foo'); 137 | 138 | await Promise.resolve(); 139 | dispatchScriptEvent('error'); 140 | 141 | await expect(stripePromise).rejects.toEqual( 142 | new Error('Failed to load Stripe.js') 143 | ); 144 | 145 | expect(console.warn).not.toHaveBeenCalled(); 146 | 147 | // start of second load, expect successful load 148 | stripePromise = loadStripe('pk_test_foo'); 149 | 150 | await new Promise((resolve) => setTimeout(resolve)); 151 | window.Stripe = jest.fn((key) => ({key})) as any; 152 | dispatchScriptEvent('load'); 153 | 154 | return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'}); 155 | }); 156 | 157 | it('rejects on first load and second load but succeeds on third load resolving with Stripe object', async () => { 158 | const {loadStripe} = require(requirePath); 159 | 160 | // start of first load, expect load failure 161 | let stripePromise = loadStripe('pk_test_foo'); 162 | 163 | await Promise.resolve(); 164 | dispatchScriptEvent('error'); 165 | 166 | await expect(stripePromise).rejects.toEqual( 167 | new Error('Failed to load Stripe.js') 168 | ); 169 | 170 | expect(console.warn).not.toHaveBeenCalled(); 171 | 172 | // start of second load, expect load failure 173 | stripePromise = loadStripe('pk_test_foo'); 174 | 175 | await Promise.resolve(); 176 | dispatchScriptEvent('error'); 177 | 178 | await expect(stripePromise).rejects.toEqual( 179 | new Error('Failed to load Stripe.js') 180 | ); 181 | 182 | expect(console.warn).not.toHaveBeenCalled(); 183 | 184 | // start of third load, expect success 185 | stripePromise = loadStripe('pk_test_foo'); 186 | 187 | await new Promise((resolve) => setTimeout(resolve)); 188 | window.Stripe = jest.fn((key) => ({key})) as any; 189 | dispatchScriptEvent('load'); 190 | 191 | return expect(stripePromise).resolves.toEqual({key: 'pk_test_foo'}); 192 | }); 193 | }); 194 | 195 | describe('loadStripe (index.ts)', () => { 196 | it('does not cause unhandled rejects when the script fails', async () => { 197 | require('./index'); 198 | 199 | await Promise.resolve(); 200 | dispatchScriptEvent('error'); 201 | 202 | // Turn the task loop to make sure the internal promise handler has been invoked 203 | await new Promise((resolve) => setImmediate(resolve)); 204 | 205 | expect(console.warn).toHaveBeenCalledWith( 206 | new Error('Failed to load Stripe.js') 207 | ); 208 | }); 209 | }); 210 | }); 211 | -------------------------------------------------------------------------------- /types/stripe-js/embedded-checkout.d.ts: -------------------------------------------------------------------------------- 1 | export type StripeEmbeddedCheckoutAddress = { 2 | country: string; 3 | line1?: string | null; 4 | line2?: string | null; 5 | city?: string | null; 6 | postal_code?: string | null; 7 | state?: string | null; 8 | }; 9 | 10 | export type StripeEmbeddedCheckoutShippingDetails = { 11 | name: string; 12 | address: StripeEmbeddedCheckoutAddress; 13 | }; 14 | 15 | export type StripeEmbeddedCheckoutShippingDetailsChangeEvent = { 16 | checkoutSessionId: string; 17 | shippingDetails: StripeEmbeddedCheckoutShippingDetails; 18 | }; 19 | 20 | export type StripeEmbeddedCheckoutLineItem = { 21 | id?: string; 22 | quantity?: number; 23 | price?: string; 24 | display?: { 25 | name?: string; 26 | description?: string; 27 | images?: string[]; 28 | }; 29 | pricingSpec?: { 30 | unitAmount?: number; 31 | unitAmountDecimal?: string; 32 | currency?: string; 33 | taxBehavior?: 'inclusive' | 'exclusive' | 'unspecified'; 34 | taxCode?: string; 35 | }; 36 | }; 37 | 38 | export type StripeEmbeddedCheckoutLineItemsChangeEvent = { 39 | checkoutSessionId: string; 40 | lineItems: StripeEmbeddedCheckoutLineItem[]; 41 | }; 42 | 43 | export type ResultAction = 44 | | {type: 'accept'} 45 | | {type: 'reject'; errorMessage?: string}; 46 | 47 | /** 48 | * Analytics types for Embedded Checkout events 49 | */ 50 | export type StripeEmbeddedCheckoutClientMetadata = { 51 | [k: string]: string; 52 | }; 53 | 54 | export type StripeEmbeddedCheckoutAnalyticsItemsAndTotals = { 55 | items?: Array<{ 56 | quantity?: number; 57 | product?: string; 58 | amount?: number; 59 | rateCard?: string; 60 | pricingPlan?: string; 61 | price?: string; 62 | }>; 63 | currency?: string; 64 | amount?: number; 65 | }; 66 | 67 | export type StripeEmbeddedCheckoutAnalyticsEvent< 68 | EventType extends string, 69 | EventDetails 70 | > = { 71 | checkoutSession: string; 72 | eventType: EventType; 73 | details: EventDetails; 74 | clientMetadata: StripeEmbeddedCheckoutClientMetadata; 75 | /** 76 | * The timestamp of the event in unix seconds 77 | */ 78 | timestamp: number; 79 | }; 80 | 81 | export type StripeEmbeddedCheckoutSubmittedDetails = StripeEmbeddedCheckoutAnalyticsItemsAndTotals & { 82 | paymentMethodType: string; 83 | }; 84 | 85 | export type StripeEmbeddedCheckoutRenderedDetails = StripeEmbeddedCheckoutAnalyticsItemsAndTotals; 86 | 87 | export type StripeEmbeddedCheckoutDeviceDataDetails = { 88 | device: { 89 | category: 'mobile' | 'tablet' | 'desktop'; 90 | language?: string; 91 | platform?: string; 92 | viewport?: {width: number; height: number}; 93 | }; 94 | }; 95 | 96 | export type StripeEmbeddedCheckoutPromotionCodeAppliedDetails = { 97 | code: string; 98 | }; 99 | 100 | export type StripeEmbeddedCheckoutSubmitFailureReason = 101 | | 'api_error' 102 | | 'user_cancelled' 103 | | 'reverification' 104 | | 'unexpected'; 105 | 106 | export type StripeEmbeddedCheckoutSubmitFailedDetails = StripeEmbeddedCheckoutAnalyticsItemsAndTotals & { 107 | paymentMethodType: string; 108 | failureReason: StripeEmbeddedCheckoutSubmitFailureReason; 109 | }; 110 | 111 | export type StripeEmbeddedCheckoutRenderedEvent = StripeEmbeddedCheckoutAnalyticsEvent< 112 | 'checkoutRendered', 113 | StripeEmbeddedCheckoutRenderedDetails 114 | >; 115 | 116 | export type StripeEmbeddedCheckoutDeviceDataEvent = StripeEmbeddedCheckoutAnalyticsEvent< 117 | 'deviceData', 118 | StripeEmbeddedCheckoutDeviceDataDetails 119 | >; 120 | 121 | export type StripeEmbeddedCheckoutPromotionCodeAppliedEvent = StripeEmbeddedCheckoutAnalyticsEvent< 122 | 'promotionCodeApplied', 123 | StripeEmbeddedCheckoutPromotionCodeAppliedDetails 124 | >; 125 | 126 | export type StripeEmbeddedCheckoutLineItemChangeEvent = StripeEmbeddedCheckoutAnalyticsEvent< 127 | 'lineItemChange', 128 | StripeEmbeddedCheckoutAnalyticsItemsAndTotals 129 | >; 130 | 131 | export type StripeEmbeddedCheckoutSubmittedEvent = StripeEmbeddedCheckoutAnalyticsEvent< 132 | 'checkoutSubmitted', 133 | StripeEmbeddedCheckoutSubmittedDetails 134 | >; 135 | 136 | export type StripeEmbeddedCheckoutSubmitFailedEvent = StripeEmbeddedCheckoutAnalyticsEvent< 137 | 'checkoutSubmitFailed', 138 | StripeEmbeddedCheckoutSubmitFailedDetails 139 | >; 140 | 141 | export type StripeEmbeddedCheckoutAnalyticsEventUnion = 142 | | StripeEmbeddedCheckoutRenderedEvent 143 | | StripeEmbeddedCheckoutDeviceDataEvent 144 | | StripeEmbeddedCheckoutPromotionCodeAppliedEvent 145 | | StripeEmbeddedCheckoutLineItemChangeEvent 146 | | StripeEmbeddedCheckoutSubmittedEvent 147 | | StripeEmbeddedCheckoutSubmitFailedEvent; 148 | 149 | export interface StripeEmbeddedCheckoutOptions { 150 | /** 151 | * The client secret of the [Checkout Session](https://stripe.com/docs/api/checkout/sessions). 152 | */ 153 | clientSecret?: string; 154 | /** 155 | * A function that returns a Promise which resolves with the client secret of 156 | * the [Checkout Session](https://stripe.com/docs/api/checkout/sessions). 157 | */ 158 | fetchClientSecret?: () => Promise; 159 | /** 160 | * onComplete is called when the Checkout Session completes successfully. 161 | * You can use it to unmount Embedded Checkout and render a custom success UI. 162 | */ 163 | onComplete?: () => void; 164 | /** 165 | * onShippingDetailsChange is called when the customer completes the shipping details form. 166 | * 167 | * The callback is required when [permissions.update.shipping_details](https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-permissions-update-shipping_details) is set to `server_only`. 168 | * For a step-by-step guide on using this callback to customize shipping options during checkout, see [Customize Shipping Options](https://docs.stripe.com/payments/checkout/custom-shipping-options). 169 | */ 170 | onShippingDetailsChange?: ( 171 | event: StripeEmbeddedCheckoutShippingDetailsChangeEvent 172 | ) => Promise; 173 | /** 174 | * onLineItemsChange is called when the customer adds, removes, or modifies a line item. 175 | * The callback is required when [permissions.update.line_items](https://docs.stripe.com/api/checkout/sessions/create#create_checkout_session-permissions-update-line_items) is set to `server_only`. 176 | */ 177 | onLineItemsChange?: ( 178 | event: StripeEmbeddedCheckoutLineItemsChangeEvent 179 | ) => Promise; 180 | /** 181 | * onAnalyticsEvent is called when analytics events occur during the checkout session. 182 | * You can use it to track customer behavior during the checkout session. 183 | */ 184 | onAnalyticsEvent?: (event: StripeEmbeddedCheckoutAnalyticsEventUnion) => void; 185 | } 186 | 187 | export interface StripeEmbeddedCheckout { 188 | /** 189 | * The `embeddedCheckout.mount` method attaches your Embedded Checkout to the DOM. 190 | * `mount` accepts either a CSS Selector (e.g., `'#checkout'`) or a DOM element. 191 | */ 192 | mount(location: string | HTMLElement): void; 193 | /** 194 | * Unmounts Embedded Checkout from the DOM. 195 | * Call `embeddedCheckout.mount` to re-attach it to the DOM. 196 | */ 197 | unmount(): void; 198 | /** 199 | * Removes Embedded Checkout from the DOM and destroys it. 200 | * Once destroyed it not be re-mounted to the DOM. 201 | * Use this if you want to create a new Embedded Checkout instance. 202 | */ 203 | destroy(): void; 204 | } 205 | -------------------------------------------------------------------------------- /types/stripe-js/elements/address.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementBase} from './base'; 2 | import {StripeError} from '../stripe'; 3 | 4 | export type StripeAddressElement = StripeElementBase & { 5 | /** 6 | * The change event is triggered when the `Element`'s value changes. 7 | */ 8 | on( 9 | eventType: 'change', 10 | handler: (event: StripeAddressElementChangeEvent) => any 11 | ): StripeAddressElement; 12 | once( 13 | eventType: 'change', 14 | handler: (event: StripeAddressElementChangeEvent) => any 15 | ): StripeAddressElement; 16 | off( 17 | eventType: 'change', 18 | handler?: (event: StripeAddressElementChangeEvent) => any 19 | ): StripeAddressElement; 20 | 21 | /** 22 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 23 | */ 24 | on( 25 | eventType: 'ready', 26 | handler: (event: {elementType: 'address'}) => any 27 | ): StripeAddressElement; 28 | once( 29 | eventType: 'ready', 30 | handler: (event: {elementType: 'address'}) => any 31 | ): StripeAddressElement; 32 | off( 33 | eventType: 'ready', 34 | handler?: (event: {elementType: 'address'}) => any 35 | ): StripeAddressElement; 36 | 37 | /** 38 | * Triggered when the element gains focus. 39 | */ 40 | on( 41 | eventType: 'focus', 42 | handler: (event: {elementType: 'address'}) => any 43 | ): StripeAddressElement; 44 | once( 45 | eventType: 'focus', 46 | handler: (event: {elementType: 'address'}) => any 47 | ): StripeAddressElement; 48 | off( 49 | eventType: 'focus', 50 | handler?: (event: {elementType: 'address'}) => any 51 | ): StripeAddressElement; 52 | 53 | /** 54 | * Triggered when the element loses focus. 55 | */ 56 | on( 57 | eventType: 'blur', 58 | handler: (event: {elementType: 'address'}) => any 59 | ): StripeAddressElement; 60 | once( 61 | eventType: 'blur', 62 | handler: (event: {elementType: 'address'}) => any 63 | ): StripeAddressElement; 64 | off( 65 | eventType: 'blur', 66 | handler?: (event: {elementType: 'address'}) => any 67 | ): StripeAddressElement; 68 | 69 | /** 70 | * Triggered when the escape key is pressed within the element. 71 | */ 72 | on( 73 | eventType: 'escape', 74 | handler: (event: {elementType: 'address'}) => any 75 | ): StripeAddressElement; 76 | once( 77 | eventType: 'escape', 78 | handler: (event: {elementType: 'address'}) => any 79 | ): StripeAddressElement; 80 | off( 81 | eventType: 'escape', 82 | handler?: (event: {elementType: 'address'}) => any 83 | ): StripeAddressElement; 84 | 85 | /** 86 | * Triggered when the element fails to load. 87 | */ 88 | on( 89 | eventType: 'loaderror', 90 | handler: (event: {elementType: 'address'; error: StripeError}) => any 91 | ): StripeAddressElement; 92 | once( 93 | eventType: 'loaderror', 94 | handler: (event: {elementType: 'address'; error: StripeError}) => any 95 | ): StripeAddressElement; 96 | off( 97 | eventType: 'loaderror', 98 | handler?: (event: {elementType: 'address'; error: StripeError}) => any 99 | ): StripeAddressElement; 100 | 101 | /** 102 | * Triggered when the loader UI is mounted to the DOM and ready to be displayed. 103 | */ 104 | on( 105 | eventType: 'loaderstart', 106 | handler: (event: {elementType: 'address'}) => any 107 | ): StripeAddressElement; 108 | once( 109 | eventType: 'loaderstart', 110 | handler: (event: {elementType: 'address'}) => any 111 | ): StripeAddressElement; 112 | off( 113 | eventType: 'loaderstart', 114 | handler?: (event: {elementType: 'address'}) => any 115 | ): StripeAddressElement; 116 | 117 | /** 118 | * Updates the options the `AddressElement` was initialized with. 119 | * Updates are merged into the existing configuration. 120 | */ 121 | update(options: Partial): StripeAddressElement; 122 | 123 | /** 124 | * Validates and retrieves form values from the `AddressElement`. 125 | */ 126 | getValue(): Promise< 127 | Pick 128 | >; 129 | }; 130 | 131 | export interface ContactOption { 132 | name: string; 133 | phone?: string; 134 | address: { 135 | line1: string; 136 | line2?: string; 137 | city: string; 138 | state: string; 139 | postal_code: string; 140 | country: string; 141 | }; 142 | } 143 | 144 | export type AddressMode = 'shipping' | 'billing'; 145 | 146 | export interface StripeAddressElementOptions { 147 | /** 148 | * Control which mode the AddressElement will be used for. 149 | */ 150 | mode: AddressMode; 151 | 152 | /** 153 | * An array of two-letter ISO country codes representing which countries 154 | * are displayed in the AddressElement. 155 | */ 156 | allowedCountries?: string[] | null; 157 | 158 | /** 159 | * Control autocomplete settings in the AddressElement. 160 | */ 161 | autocomplete?: 162 | | {mode: 'automatic'} 163 | | {mode: 'disabled'} 164 | | {mode: 'google_maps_api'; apiKey: string}; 165 | 166 | /** 167 | * Whether or not AddressElement accepts PO boxes 168 | */ 169 | blockPoBox?: boolean; 170 | 171 | /** 172 | * An array of saved addresses. 173 | */ 174 | contacts?: ContactOption[]; 175 | 176 | /** 177 | * Default value for AddressElement fields 178 | */ 179 | defaultValues?: { 180 | name?: string | null; 181 | firstName?: string | null; 182 | lastName?: string | null; 183 | address?: { 184 | line1?: string | null; 185 | line2?: string | null; 186 | city?: string | null; 187 | state?: string | null; 188 | postal_code?: string | null; 189 | country: string; 190 | }; 191 | phone?: string | null; 192 | }; 193 | 194 | /** 195 | * Control which additional fields to display in the AddressElement. 196 | */ 197 | fields?: { 198 | phone?: 'always' | 'never' | 'auto'; 199 | }; 200 | 201 | /** 202 | * Specify validation rules for the above additional fields. 203 | */ 204 | validation?: { 205 | phone?: { 206 | required: 'always' | 'never' | 'auto'; 207 | }; 208 | }; 209 | 210 | /** 211 | * Specify display options in the AddressElement 212 | */ 213 | display?: { 214 | name?: 'full' | 'split' | 'organization'; 215 | }; 216 | } 217 | 218 | export interface StripeAddressElementChangeEvent { 219 | /** 220 | * The type of element that emitted this event. 221 | */ 222 | elementType: 'address'; 223 | 224 | /** 225 | * The mode of the AddressElement that emitted this event. 226 | */ 227 | elementMode: AddressMode; 228 | 229 | /** 230 | * Whether or not the AddressElement is currently empty. 231 | */ 232 | empty: boolean; 233 | 234 | /** 235 | * Whether or not the AddressElement is complete. 236 | */ 237 | complete: boolean; 238 | 239 | /** 240 | * Whether or not the address is new. 241 | */ 242 | isNewAddress: boolean; 243 | 244 | /** 245 | * An object containing the current address. 246 | */ 247 | value: { 248 | name: string; 249 | firstName?: string; 250 | lastName?: string; 251 | address: { 252 | line1: string; 253 | line2: string | null; 254 | city: string; 255 | state: string; 256 | postal_code: string; 257 | country: string; 258 | }; 259 | phone?: string; 260 | }; 261 | } 262 | 263 | export interface StripeAddressElementGetElementOptions { 264 | mode: AddressMode; 265 | } 266 | -------------------------------------------------------------------------------- /types/stripe-js/elements/card.d.ts: -------------------------------------------------------------------------------- 1 | import { 2 | StripeElementBase, 3 | StripeElementStyle, 4 | StripeElementClasses, 5 | StripeElementChangeEvent, 6 | } from './base'; 7 | import {StripeError} from '../stripe'; 8 | import {CardNetworkBrand} from '../elements-group'; 9 | 10 | export type StripeCardElement = StripeElementBase & { 11 | /** 12 | * The change event is triggered when the `Element`'s value changes. 13 | */ 14 | on( 15 | eventType: 'change', 16 | handler: (event: StripeCardElementChangeEvent) => any 17 | ): StripeCardElement; 18 | once( 19 | eventType: 'change', 20 | handler: (event: StripeCardElementChangeEvent) => any 21 | ): StripeCardElement; 22 | off( 23 | eventType: 'change', 24 | handler?: (event: StripeCardElementChangeEvent) => any 25 | ): StripeCardElement; 26 | 27 | /** 28 | * Triggered when the element is fully rendered and can accept `element.focus` calls. 29 | */ 30 | on( 31 | eventType: 'ready', 32 | handler: (event: {elementType: 'card'}) => any 33 | ): StripeCardElement; 34 | once( 35 | eventType: 'ready', 36 | handler: (event: {elementType: 'card'}) => any 37 | ): StripeCardElement; 38 | off( 39 | eventType: 'ready', 40 | handler?: (event: {elementType: 'card'}) => any 41 | ): StripeCardElement; 42 | 43 | /** 44 | * Triggered when the element gains focus. 45 | */ 46 | on( 47 | eventType: 'focus', 48 | handler: (event: {elementType: 'card'}) => any 49 | ): StripeCardElement; 50 | once( 51 | eventType: 'focus', 52 | handler: (event: {elementType: 'card'}) => any 53 | ): StripeCardElement; 54 | off( 55 | eventType: 'focus', 56 | handler?: (event: {elementType: 'card'}) => any 57 | ): StripeCardElement; 58 | 59 | /** 60 | * Triggered when the element loses focus. 61 | */ 62 | on( 63 | eventType: 'blur', 64 | handler: (event: {elementType: 'card'}) => any 65 | ): StripeCardElement; 66 | once( 67 | eventType: 'blur', 68 | handler: (event: {elementType: 'card'}) => any 69 | ): StripeCardElement; 70 | off( 71 | eventType: 'blur', 72 | handler?: (event: {elementType: 'card'}) => any 73 | ): StripeCardElement; 74 | 75 | /** 76 | * Triggered when the escape key is pressed within the element. 77 | */ 78 | on( 79 | eventType: 'escape', 80 | handler: (event: {elementType: 'card'}) => any 81 | ): StripeCardElement; 82 | once( 83 | eventType: 'escape', 84 | handler: (event: {elementType: 'card'}) => any 85 | ): StripeCardElement; 86 | off( 87 | eventType: 'escape', 88 | handler?: (event: {elementType: 'card'}) => any 89 | ): StripeCardElement; 90 | 91 | /** 92 | * Triggered when there is a change to the available networks the provided card can run on. 93 | */ 94 | on( 95 | eventType: 'networkschange', 96 | handler: (event: {elementType: 'card'}) => any 97 | ): StripeCardElement; 98 | once( 99 | eventType: 'networkschange', 100 | handler: (event: {elementType: 'card'}) => any 101 | ): StripeCardElement; 102 | off( 103 | eventType: 'networkschange', 104 | handler?: (event: {elementType: 'card'}) => any 105 | ): StripeCardElement; 106 | 107 | /** 108 | * Triggered when the element fails to load. 109 | */ 110 | on( 111 | eventType: 'loaderror', 112 | handler: (event: {elementType: 'card'; error: StripeError}) => any 113 | ): StripeCardElement; 114 | once( 115 | eventType: 'loaderror', 116 | handler: (event: {elementType: 'card'; error: StripeError}) => any 117 | ): StripeCardElement; 118 | off( 119 | eventType: 'loaderror', 120 | handler?: (event: {elementType: 'card'; error: StripeError}) => any 121 | ): StripeCardElement; 122 | 123 | /** 124 | * Updates the options the `CardElement` was initialized with. 125 | * Updates are merged into the existing configuration. 126 | * 127 | * The styles of an `CardElement` can be dynamically changed using `element.update`. 128 | * This method can be used to simulate CSS media queries that automatically adjust the size of elements when viewed on different devices. 129 | */ 130 | update(options: StripeCardElementUpdateOptions): void; 131 | }; 132 | 133 | export interface StripeCardElementOptions { 134 | classes?: StripeElementClasses; 135 | 136 | style?: StripeElementStyle; 137 | 138 | /** 139 | * A pre-filled set of values to include in the input (e.g., `{postalCode: '94110'}`). 140 | * Note that sensitive card information (card number, CVC, and expiration date) cannot be pre-filled. 141 | */ 142 | value?: {postalCode?: string}; 143 | 144 | /** 145 | * Hide the postal code field. 146 | * Default is `false`. 147 | * If you are already collecting a full billing address or postal code elsewhere, set this to `true`. 148 | */ 149 | hidePostalCode?: boolean; 150 | 151 | /** 152 | * Appearance of the icon in the Element. 153 | */ 154 | iconStyle?: 'default' | 'solid'; 155 | 156 | /** 157 | * Hides the icon in the Element. 158 | * Default is `false`. 159 | */ 160 | hideIcon?: boolean; 161 | 162 | /** 163 | * Applies a disabled state to the Element such that user input is not accepted. 164 | * Default is `false`. 165 | */ 166 | disabled?: boolean; 167 | 168 | /** 169 | * Hides and disables the Link Button in the Card Element. 170 | * Default is `false`. 171 | */ 172 | disableLink?: boolean; 173 | 174 | /** 175 | * Specifies a network preference for Card Brand Choice. The first network in the array which is a valid 176 | * network on the entered card will be selected as the default in the Card Brand Choice dropdown upon 177 | * entry of a co-branded card. 178 | * 179 | * Default is an empty array, meaning no default selection will be made in the Card Brand choice dropdown. 180 | */ 181 | preferredNetwork?: Array; 182 | } 183 | 184 | export interface StripeCardElementUpdateOptions { 185 | classes?: StripeElementClasses; 186 | 187 | style?: StripeElementStyle; 188 | 189 | /** 190 | * A pre-filled set of values to include in the input (e.g., `{postalCode: '94110'}`). 191 | * Note that sensitive card information (card number, CVC, and expiration date) cannot be pre-filled. 192 | */ 193 | value?: {postalCode?: string}; 194 | 195 | /** 196 | * Hide the postal code field. 197 | * Default is `false`. 198 | * If you are already collecting a full billing address or postal code elsewhere, set this to `true`. 199 | */ 200 | hidePostalCode?: boolean; 201 | 202 | /** 203 | * Appearance of the icon in the Element. 204 | */ 205 | iconStyle?: 'default' | 'solid'; 206 | 207 | /** 208 | * Hides the icon in the Element. 209 | * Default is `false`. 210 | */ 211 | hideIcon?: boolean; 212 | 213 | /** 214 | * Applies a disabled state to the Element such that user input is not accepted. 215 | * Default is `false`. 216 | */ 217 | disabled?: boolean; 218 | } 219 | 220 | export interface StripeCardElementChangeEvent extends StripeElementChangeEvent { 221 | /** 222 | * The type of element that emitted this event. 223 | */ 224 | elementType: 'card'; 225 | 226 | /** 227 | * An object containing the currently entered `postalCode`. 228 | */ 229 | value: {postalCode: string}; 230 | 231 | /* 232 | * The card brand of the card number being entered. 233 | */ 234 | brand: 235 | | 'visa' 236 | | 'mastercard' 237 | | 'amex' 238 | | 'discover' 239 | | 'diners' 240 | | 'jcb' 241 | | 'unionpay' 242 | | 'unknown'; 243 | } 244 | -------------------------------------------------------------------------------- /types/api/setup-intents.d.ts: -------------------------------------------------------------------------------- 1 | import {PaymentMethod} from './payment-methods'; 2 | 3 | /** 4 | * The SetupIntent object. 5 | */ 6 | export interface SetupIntent { 7 | /** 8 | * Unique identifier for the object. 9 | */ 10 | id: string; 11 | 12 | /** 13 | * String representing the object's type. Objects of the same type share the same value. 14 | */ 15 | object: 'setup_intent'; 16 | 17 | /** 18 | * Reason for cancellation of this SetupIntent, one of `abandoned`, `requested_by_customer`, or `duplicate`. 19 | */ 20 | cancellation_reason: SetupIntent.CancellationReason | null; 21 | 22 | /** 23 | * The client secret of this SetupIntent. Used for client-side retrieval using a publishable key. 24 | * 25 | * The client secret can be used to complete payment setup from your frontend. It should not be stored, logged, embedded in URLs, or exposed to anyone other than the customer. Make sure that you have TLS enabled on any page that includes the client secret. 26 | */ 27 | client_secret: string | null; 28 | 29 | /** 30 | * Time at which the object was created. Measured in seconds since the Unix epoch. 31 | */ 32 | created: number; 33 | 34 | /** 35 | * An arbitrary string attached to the object. Often useful for displaying to users. 36 | */ 37 | description: string | null; 38 | 39 | /** 40 | * The error encountered in the previous SetupIntent confirmation. 41 | */ 42 | last_setup_error: SetupIntent.LastSetupError | null; 43 | 44 | /** 45 | * Has the value `true` if the object exists in live mode or the value `false` if the object exists in test mode. 46 | */ 47 | livemode: boolean; 48 | 49 | /** 50 | * If present, this property tells you what actions you need to take in order for your customer to continue payment setup. 51 | */ 52 | next_action: SetupIntent.NextAction | null; 53 | 54 | /** 55 | * ID of the payment method used with this SetupIntent, or the PaymentMethod itself if this field is expanded. 56 | */ 57 | payment_method: string | null | PaymentMethod; 58 | 59 | /** 60 | * The list of payment method types (e.g. card) that this SetupIntent is allowed to set up. 61 | */ 62 | payment_method_types: Array; 63 | 64 | /** 65 | * [Status](https://stripe.com/docs/payments/intents#intent-statuses) of this SetupIntent, one of `requires_payment_method`, `requires_confirmation`, `requires_action`, `processing`, `canceled`, or `succeeded`. 66 | */ 67 | status: SetupIntent.Status; 68 | 69 | /** 70 | * Indicates how the payment method is intended to be used in the future. 71 | * 72 | * Use `on_session` if you intend to only reuse the payment method when the customer is in your checkout flow. Use `off_session` if your customer may or may not be in your checkout flow. If not provided, this value defaults to `off_session`. 73 | */ 74 | usage: string; 75 | } 76 | 77 | export namespace SetupIntent { 78 | export type CancellationReason = 79 | | 'abandoned' 80 | | 'duplicate' 81 | | 'requested_by_customer'; 82 | 83 | export interface LastSetupError { 84 | /** 85 | * For card errors, the ID of the failed charge. 86 | */ 87 | charge?: string; 88 | 89 | /** 90 | * For some errors that could be handled programmatically, a short string indicating the [error code](https://stripe.com/docs/error-codes) reported. 91 | */ 92 | code?: string; 93 | 94 | /** 95 | * For card errors resulting from a card issuer decline, a short string indicating the [card issuer's reason for the decline](https://stripe.com/docs/declines#issuer-declines) if they provide one. 96 | */ 97 | decline_code?: string; 98 | 99 | /** 100 | * A URL to more information about the [error code](https://stripe.com/docs/error-codes) reported. 101 | */ 102 | doc_url?: string; 103 | 104 | /** 105 | * A human-readable message providing more details about the error. For card errors, these messages can be shown to your users. 106 | */ 107 | message?: string; 108 | 109 | /** 110 | * 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. 111 | */ 112 | param?: string; 113 | 114 | payment_method?: PaymentMethod; 115 | 116 | /** 117 | * 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` 118 | */ 119 | type: LastSetupError.Type; 120 | } 121 | 122 | export namespace LastSetupError { 123 | export type Type = 124 | | 'api_connection_error' 125 | | 'api_error' 126 | | 'authentication_error' 127 | | 'card_error' 128 | | 'idempotency_error' 129 | | 'invalid_request_error' 130 | | 'rate_limit_error'; 131 | } 132 | 133 | export interface NextAction { 134 | /** 135 | * Type of the next action to perform, one of `redirect_to_url`, `use_stripe_sdk`, or `verify_with_microdeposits`. 136 | */ 137 | type: string; 138 | 139 | /** 140 | * Contains instructions for authenticating a payment by redirecting your customer to another page or application. 141 | */ 142 | redirect_to_url?: NextAction.RedirectToUrl; 143 | 144 | /** 145 | * When confirming a SetupIntent with Stripe.js, Stripe.js depends on the contents of this dictionary to invoke authentication flows. The shape of the contents is subject to change and is only intended to be used by Stripe.js. 146 | */ 147 | use_stripe_sdk?: NextAction.UseStripeSdk; 148 | 149 | /** 150 | * Contains details describing microdeposits verification flow. 151 | */ 152 | verify_with_microdeposits?: NextAction.VerifyWithMicrodeposits; 153 | } 154 | 155 | export namespace NextAction { 156 | export interface RedirectToUrl { 157 | /** 158 | * If the customer does not exit their browser while authenticating, they will be redirected to this specified URL after completion. 159 | */ 160 | return_url: string | null; 161 | 162 | /** 163 | * The URL you must redirect your customer to in order to authenticate. 164 | */ 165 | url: string | null; 166 | } 167 | 168 | export interface UseStripeSdk {} 169 | 170 | export interface VerifyWithMicrodeposits { 171 | /** 172 | * The timestamp when the microdeposits are expected to land. 173 | */ 174 | arrival_date: number; 175 | 176 | /** 177 | * The URL for the hosted verification page, which allows customers to verify their bank account. 178 | */ 179 | hosted_verification_url: string; 180 | 181 | /** 182 | * The type of the microdeposit sent to the customer. Used to distinguish between different verification methods. 183 | */ 184 | microdeposit_type: string | null; 185 | } 186 | } 187 | 188 | export type Status = 189 | | 'canceled' 190 | | 'processing' 191 | | 'requires_action' 192 | | 'requires_confirmation' 193 | | 'requires_payment_method' 194 | | 'succeeded'; 195 | } 196 | 197 | export interface SetupIntentConfirmParams { 198 | /** 199 | * This hash contains details about the Mandate to create 200 | */ 201 | mandate_data?: {[k: string]: any}; 202 | 203 | /** 204 | * The URL to redirect your customer back to after they authenticate on the payment method's app or site. 205 | * If you'd prefer to redirect to a mobile application, you can alternatively supply an application URI scheme. 206 | * This parameter is only used for cards and other redirect-based payment methods. 207 | */ 208 | return_url?: string; 209 | } 210 | -------------------------------------------------------------------------------- /scripts/publish: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | RELEASE_TYPE=${1:-} 7 | IS_RELEASE_CANDIDATE=$(node scripts/is_release_candidate.js) 8 | 9 | echo_help() { 10 | cat << EOF 11 | USAGE: 12 | ./scripts/publish 13 | 14 | ARGS: 15 | 16 | A Semantic Versioning release type used to bump the version number. Either "patch", "minor", or "major". 17 | EOF 18 | } 19 | 20 | verify_prerequisites() { 21 | echo "Verifying prerequisites..." 22 | 23 | # Check npm login status 24 | if ! npm whoami &> /dev/null; then 25 | echo "Error! You are not logged in to npm." 26 | echo "Please run 'npm login' and try again." 27 | exit 1 28 | fi 29 | 30 | # Check yarn login status 31 | if ! yarn login --silent &> /dev/null; then 32 | echo "Error! You are not logged in to yarn." 33 | echo "Please run 'yarn login' and try again." 34 | exit 1 35 | fi 36 | 37 | # Check for hub command 38 | if ! which hub &> /dev/null; then 39 | echo "Error! 'hub' command not found." 40 | echo "Please install hub with 'brew install hub'." 41 | exit 1 42 | fi 43 | 44 | # Check GitHub token 45 | if [[ -z "${GITHUB_TOKEN:-}" ]]; then 46 | echo "Error! GITHUB_TOKEN environment variable is not set." 47 | exit 1 48 | fi 49 | 50 | # Check git signing configuration 51 | if [ "$(git config --get gpg.format)" != "ssh" ]; then 52 | echo "Error! Git is not configured to use SSH for commit signing." 53 | echo "Please run: git config --global gpg.format ssh" 54 | exit 1 55 | fi 56 | 57 | # Check signing key configuration 58 | if [ -z "$(git config --get user.signingkey)" ]; then 59 | echo "Error! Git signing key is not configured." 60 | echo "Please run: git config --global user.signingkey ~/.ssh/id_ed25519.pub" 61 | exit 1 62 | fi 63 | 64 | # Check if signing key exists 65 | local signing_key=$(git config --get user.signingkey) 66 | if [ ! -f "$signing_key" ]; then 67 | echo "Error! Git signing key does not exist at: $signing_key" 68 | echo "Please set up SSH key for signing as described in the documentation." 69 | exit 1 70 | fi 71 | 72 | # Check if commit signing is enabled 73 | if [ "$(git config --get commit.gpgsign)" != "true" ]; then 74 | echo "Error! Git commit signing is not enabled." 75 | echo "Please run: git config --global commit.gpgsign true" 76 | exit 1 77 | fi 78 | 79 | echo "All prerequisites verified successfully!" 80 | } 81 | 82 | create_github_release() { 83 | if which hub | grep -q "not found"; then 84 | create_github_release_fallback 85 | return 86 | fi 87 | 88 | # Get the last two non-release-candidate releases. For example, `("v1.3.1" "v1.3.2")` 89 | local versions=($(git tag --sort version:refname | grep '^v' | grep -v "rc" | tail -n 2)) 90 | 91 | # If we didn't find exactly two previous version versions, give up 92 | if [ ${#versions[@]} -ne 2 ]; then 93 | create_github_release_fallback 94 | return 95 | fi 96 | 97 | local previous_version="${versions[0]}" 98 | local current_version="${versions[1]}" 99 | local commit_titles=$(git log --pretty=format:"- %s" "$previous_version".."$current_version"^) 100 | local release_notes="$(cat << EOF 101 | $current_version 102 | 103 | 104 | 105 | 106 | $commit_titles 107 | 108 | ### New features 109 | 110 | ### Fixes 111 | 112 | ### Changed 113 | 114 | EOF 115 | )" 116 | 117 | echo "Creating GitHub release" 118 | echo "" 119 | echo -n " " 120 | hub release create -em "$release_notes" "$current_version" 121 | } 122 | 123 | create_github_release_fallback() { 124 | cat << EOF 125 | Remember to create a release on GitHub with a changelog notes: 126 | 127 | https://github.com/stripe/stripe-js/releases/new 128 | 129 | EOF 130 | } 131 | 132 | verify_commit_is_signed() { 133 | local commit_hash=$(git log -1 --format="%H") 134 | 135 | if git show --no-patch --pretty=format:"%G?" "$commit_hash" | grep "N" &> /dev/null; then 136 | echo "Error! Commit $commit_hash is not signed" 137 | echo "Please follow https://docs.github.com/en/authentication/managing-commit-signature-verification/adding-a-gpg-key-to-your-github-account and sign your commit" 138 | exit 1 139 | fi 140 | } 141 | 142 | # Require release type when not a beta release 143 | # Not necessary for beta releases because the prerelease versions 144 | # can be incremented automatically 145 | if [ "$IS_RELEASE_CANDIDATE" -ne 1 ]; then 146 | 147 | # Show help if no arguments passed 148 | if [ $# -eq 0 ]; then 149 | echo "Error! Missing release type argument" 150 | echo "" 151 | echo_help 152 | exit 1 153 | fi 154 | 155 | # Validate passed release type 156 | case $RELEASE_TYPE in 157 | patch | minor | major) 158 | ;; 159 | 160 | *) 161 | echo "Error! Invalid release type supplied" 162 | echo "" 163 | echo_help 164 | exit 1 165 | ;; 166 | esac 167 | fi 168 | 169 | # Show help message if -h, --help, or help passed 170 | case "${1:-}" in 171 | -h | --help | help) 172 | echo_help 173 | exit 0 174 | ;; 175 | esac 176 | 177 | # Make sure our working dir is the repo root directory 178 | cd "$(git rev-parse --show-toplevel)" 179 | 180 | verify_prerequisites 181 | 182 | echo "Fetching git remotes" 183 | git fetch 184 | 185 | GIT_STATUS=$(git status) 186 | 187 | if ! grep -q 'On branch master' <<< "$GIT_STATUS"; then 188 | echo "Error! Must be on master branch to publish" 189 | exit 1 190 | fi 191 | 192 | if ! grep -q "Your branch is up to date with 'origin/master'." <<< "$GIT_STATUS"; then 193 | echo "Error! Must be up to date with origin/master to publish" 194 | exit 1 195 | fi 196 | 197 | if ! grep -q 'working tree clean' <<< "$GIT_STATUS"; then 198 | echo "Error! Cannot publish with dirty working tree" 199 | exit 1 200 | fi 201 | 202 | echo "Installing dependencies according to lockfile" 203 | yarn install --frozen-lockfile 204 | 205 | echo "Bumping package.json $RELEASE_TYPE version and tagging commit" 206 | if [ "$IS_RELEASE_CANDIDATE" -eq 1 ]; then 207 | # The Github changelog is based on tag history, so do not create tags for beta versions 208 | # rc = release candidate 209 | if [ -z "$RELEASE_TYPE" ]; then 210 | # increment only the prerelease version if necessary, e.g. 211 | # 1.2.3-rc.0 -> 1.2.3-rc.1 212 | # 1.2.3 -> 1.2.3-rc.0 213 | yarn version --prerelease --preid=rc 214 | else 215 | # always increment the main version, e.g. 216 | # patch: 1.2.3-rc.0 -> 1.2.4-rc.0 217 | # patch: 1.2.3 -> 1.2.4-rc.0 218 | # major: 1.2.3 -> 2.0.0-rc.0 219 | yarn version "--pre$RELEASE_TYPE" --preid=rc 220 | fi 221 | else 222 | # increment the main version with no prerelease version, e.g. 223 | # patch: 1.2.3-rc.0 -> 1.2.4 224 | # major: 1.2.3 -> 2.0.0 225 | yarn version "--$RELEASE_TYPE" 226 | fi 227 | 228 | echo "Building" 229 | yarn run build 230 | 231 | echo "Running tests" 232 | yarn run test 233 | 234 | verify_commit_is_signed 235 | 236 | echo "Pushing git commit and tag" 237 | git push --follow-tags 238 | 239 | if [ "$IS_RELEASE_CANDIDATE" -ne 1 ]; then 240 | # Create release after commit and tag are pushed to ensure package.json 241 | # is bumped in the GitHub release. 242 | create_github_release 243 | fi 244 | 245 | echo "Publishing release" 246 | if [ "$IS_RELEASE_CANDIDATE" -eq 1 ]; then 247 | yarn --ignore-scripts publish --tag=rc --non-interactive --access=public 248 | else 249 | yarn --ignore-scripts publish --non-interactive --access=public 250 | fi 251 | 252 | echo "Publish successful!" 253 | echo "" 254 | -------------------------------------------------------------------------------- /types/stripe-js/elements/base.d.ts: -------------------------------------------------------------------------------- 1 | import {StripeElementType} from '../elements-group'; 2 | 3 | export type StripeElementBase = { 4 | /** 5 | * The `element.mount` method attaches your [Element](https://stripe.com/docs/js/element) to the DOM. 6 | * `element.mount` accepts either a CSS Selector (e.g., `'#card-element'`) or a DOM element. 7 | * 8 | * You need to create a container DOM element to mount an `Element`. 9 | * If the container DOM element has a label, the `Element` is automatically focused when its label is clicked. 10 | * There are two ways to do this: 11 | * 12 | * 1. Mount the instance within a `