stripe 8.186.0 → 8.189.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 8.189.0 - 2021-11-16
4
+ * [#1295](https://github.com/stripe/stripe-node/pull/1295) API Updates
5
+ * Add support for new resource `ShippingRate`
6
+ * Add support for `shipping_options` on `CheckoutSessionCreateParams` and `Checkout.Session`
7
+ * Add support for `shipping_rate` on `Checkout.Session`
8
+
9
+ ## 8.188.0 - 2021-11-12
10
+ * [#1293](https://github.com/stripe/stripe-node/pull/1293) API Updates
11
+ * Add support for new value `agrobank` on enums `Charge.payment_method_details.fpx.bank`, `PaymentIntentCreateParams.payment_method_data.fpx.bank`, `PaymentIntentUpdateParams.payment_method_data.fpx.bank`, `PaymentIntentConfirmParams.payment_method_data.fpx.bank`, `PaymentMethodCreateParams.fpx.bank`, and `PaymentMethod.fpx.bank`
12
+
13
+ ## 8.187.0 - 2021-11-11
14
+ * [#1292](https://github.com/stripe/stripe-node/pull/1292) API Updates
15
+ * Add support for `expire` method on resource `Checkout.Session`
16
+ * Add support for `status` on `Checkout.Session`
17
+ * [#1288](https://github.com/stripe/stripe-node/pull/1288) Add SubtleCryptoProvider and update Webhooks to allow async crypto.
18
+ * [#1291](https://github.com/stripe/stripe-node/pull/1291) Better types in `lib.d.ts`
19
+
20
+ ## 8.186.1 - 2021-11-04
21
+ * [#1284](https://github.com/stripe/stripe-node/pull/1284) API Updates
22
+ * Remove support for `ownership_declaration_shown_and_signed` on `TokenCreateParams.account`. This API was unused.
23
+ * Add support for `ownership_declaration_shown_and_signed` on `TokenCreateParams.account.company`
24
+
25
+
3
26
  ## 8.186.0 - 2021-11-01
4
27
  * [#1283](https://github.com/stripe/stripe-node/pull/1283) API Updates
5
28
  * Add support for `ownership_declaration` on `AccountUpdateParams.company`, `AccountCreateParams.company`, `Account.company`, and `TokenCreateParams.account.company`
package/VERSION CHANGED
@@ -1 +1 @@
1
- 8.186.0
1
+ 8.189.0
package/lib/Webhooks.js CHANGED
@@ -19,6 +19,25 @@ const Webhook = {
19
19
  return jsonPayload;
20
20
  },
21
21
 
22
+ async constructEventAsync(
23
+ payload,
24
+ header,
25
+ secret,
26
+ tolerance,
27
+ cryptoProvider
28
+ ) {
29
+ await this.signature.verifyHeaderAsync(
30
+ payload,
31
+ header,
32
+ secret,
33
+ tolerance || Webhook.DEFAULT_TOLERANCE,
34
+ cryptoProvider
35
+ );
36
+
37
+ const jsonPayload = JSON.parse(payload);
38
+ return jsonPayload;
39
+ },
40
+
22
41
  /**
23
42
  * Generates a header to be used for webhook mocking
24
43
  *
@@ -62,81 +81,156 @@ const Webhook = {
62
81
  const signature = {
63
82
  EXPECTED_SCHEME: 'v1',
64
83
 
65
- verifyHeader(payload, header, secret, tolerance, cryptoProvider) {
66
- payload = Buffer.isBuffer(payload) ? payload.toString('utf8') : payload;
84
+ verifyHeader(
85
+ encodedPayload,
86
+ encodedHeader,
87
+ secret,
88
+ tolerance,
89
+ cryptoProvider
90
+ ) {
91
+ const {
92
+ decodedHeader: header,
93
+ decodedPayload: payload,
94
+ details,
95
+ } = parseEventDetails(encodedPayload, encodedHeader, this.EXPECTED_SCHEME);
67
96
 
68
- // Express's type for `Request#headers` is `string | []string`
69
- // which is because the `set-cookie` header is an array,
70
- // but no other headers are an array (docs: https://nodejs.org/api/http.html#http_message_headers)
71
- // (Express's Request class is an extension of http.IncomingMessage, and doesn't appear to be relevantly modified: https://github.com/expressjs/express/blob/master/lib/request.js#L31)
72
- if (Array.isArray(header)) {
73
- throw new Error(
74
- 'Unexpected: An array was passed as a header, which should not be possible for the stripe-signature header.'
75
- );
76
- }
77
-
78
- header = Buffer.isBuffer(header) ? header.toString('utf8') : header;
97
+ cryptoProvider = cryptoProvider || getNodeCryptoProvider();
98
+ const expectedSignature = cryptoProvider.computeHMACSignature(
99
+ makeHMACContent(payload, details),
100
+ secret
101
+ );
79
102
 
80
- const details = parseHeader(header, this.EXPECTED_SCHEME);
103
+ validateComputedSignature(
104
+ payload,
105
+ header,
106
+ details,
107
+ expectedSignature,
108
+ tolerance
109
+ );
81
110
 
82
- if (!details || details.timestamp === -1) {
83
- throw new StripeSignatureVerificationError({
84
- message: 'Unable to extract timestamp and signatures from header',
85
- detail: {
86
- header,
87
- payload,
88
- },
89
- });
90
- }
111
+ return true;
112
+ },
91
113
 
92
- if (!details.signatures.length) {
93
- throw new StripeSignatureVerificationError({
94
- message: 'No signatures found with expected scheme',
95
- detail: {
96
- header,
97
- payload,
98
- },
99
- });
100
- }
114
+ async verifyHeaderAsync(
115
+ encodedPayload,
116
+ encodedHeader,
117
+ secret,
118
+ tolerance,
119
+ cryptoProvider
120
+ ) {
121
+ const {
122
+ decodedHeader: header,
123
+ decodedPayload: payload,
124
+ details,
125
+ } = parseEventDetails(encodedPayload, encodedHeader, this.EXPECTED_SCHEME);
101
126
 
102
127
  cryptoProvider = cryptoProvider || getNodeCryptoProvider();
103
- const expectedSignature = cryptoProvider.computeHMACSignature(
104
- `${details.timestamp}.${payload}`,
128
+
129
+ const expectedSignature = await cryptoProvider.computeHMACSignatureAsync(
130
+ makeHMACContent(payload, details),
105
131
  secret
106
132
  );
107
133
 
108
- const signatureFound = !!details.signatures.filter(
109
- utils.secureCompare.bind(utils, expectedSignature)
110
- ).length;
111
-
112
- if (!signatureFound) {
113
- throw new StripeSignatureVerificationError({
114
- message:
115
- 'No signatures found matching the expected signature for payload.' +
116
- ' Are you passing the raw request body you received from Stripe?' +
117
- ' https://github.com/stripe/stripe-node#webhook-signing',
118
- detail: {
119
- header,
120
- payload,
121
- },
122
- });
123
- }
134
+ return validateComputedSignature(
135
+ payload,
136
+ header,
137
+ details,
138
+ expectedSignature,
139
+ tolerance
140
+ );
141
+ },
142
+ };
124
143
 
125
- const timestampAge = Math.floor(Date.now() / 1000) - details.timestamp;
144
+ function makeHMACContent(payload, details) {
145
+ return `${details.timestamp}.${payload}`;
146
+ }
126
147
 
127
- if (tolerance > 0 && timestampAge > tolerance) {
128
- throw new StripeSignatureVerificationError({
129
- message: 'Timestamp outside the tolerance zone',
130
- detail: {
131
- header,
132
- payload,
133
- },
134
- });
135
- }
148
+ function parseEventDetails(encodedPayload, encodedHeader, expectedScheme) {
149
+ const decodedPayload = Buffer.isBuffer(encodedPayload)
150
+ ? encodedPayload.toString('utf8')
151
+ : encodedPayload;
152
+
153
+ // Express's type for `Request#headers` is `string | []string`
154
+ // which is because the `set-cookie` header is an array,
155
+ // but no other headers are an array (docs: https://nodejs.org/api/http.html#http_message_headers)
156
+ // (Express's Request class is an extension of http.IncomingMessage, and doesn't appear to be relevantly modified: https://github.com/expressjs/express/blob/master/lib/request.js#L31)
157
+ if (Array.isArray(encodedHeader)) {
158
+ throw new Error(
159
+ 'Unexpected: An array was passed as a header, which should not be possible for the stripe-signature header.'
160
+ );
161
+ }
136
162
 
137
- return true;
138
- },
139
- };
163
+ const decodedHeader = Buffer.isBuffer(encodedHeader)
164
+ ? encodedHeader.toString('utf8')
165
+ : encodedHeader;
166
+
167
+ const details = parseHeader(decodedHeader, expectedScheme);
168
+
169
+ if (!details || details.timestamp === -1) {
170
+ throw new StripeSignatureVerificationError({
171
+ message: 'Unable to extract timestamp and signatures from header',
172
+ detail: {
173
+ decodedHeader,
174
+ decodedPayload,
175
+ },
176
+ });
177
+ }
178
+
179
+ if (!details.signatures.length) {
180
+ throw new StripeSignatureVerificationError({
181
+ message: 'No signatures found with expected scheme',
182
+ detail: {
183
+ decodedHeader,
184
+ decodedPayload,
185
+ },
186
+ });
187
+ }
188
+
189
+ return {
190
+ decodedPayload,
191
+ decodedHeader,
192
+ details,
193
+ };
194
+ }
195
+
196
+ function validateComputedSignature(
197
+ payload,
198
+ header,
199
+ details,
200
+ expectedSignature,
201
+ tolerance
202
+ ) {
203
+ const signatureFound = !!details.signatures.filter(
204
+ utils.secureCompare.bind(utils, expectedSignature)
205
+ ).length;
206
+
207
+ if (!signatureFound) {
208
+ throw new StripeSignatureVerificationError({
209
+ message:
210
+ 'No signatures found matching the expected signature for payload.' +
211
+ ' Are you passing the raw request body you received from Stripe?' +
212
+ ' https://github.com/stripe/stripe-node#webhook-signing',
213
+ detail: {
214
+ header,
215
+ payload,
216
+ },
217
+ });
218
+ }
219
+
220
+ const timestampAge = Math.floor(Date.now() / 1000) - details.timestamp;
221
+
222
+ if (tolerance > 0 && timestampAge > tolerance) {
223
+ throw new StripeSignatureVerificationError({
224
+ message: 'Timestamp outside the tolerance zone',
225
+ detail: {
226
+ header,
227
+ payload,
228
+ },
229
+ });
230
+ }
231
+
232
+ return true;
233
+ }
140
234
 
141
235
  function parseHeader(header, scheme) {
142
236
  if (typeof header !== 'string') {
@@ -16,6 +16,21 @@ class CryptoProvider {
16
16
  computeHMACSignature(payload, secret) {
17
17
  throw new Error('computeHMACSignature not implemented.');
18
18
  }
19
+
20
+ /**
21
+ * Asynchronous version of `computeHMACSignature`. Some implementations may
22
+ * only allow support async signature computation.
23
+ *
24
+ * Computes a SHA-256 HMAC given a secret and a payload (encoded in UTF-8).
25
+ * The output HMAC should be encoded in hexadecimal.
26
+ *
27
+ * Sample values for implementations:
28
+ * - computeHMACSignature('', 'test_secret') => 'f7f9bd47fb987337b5796fdc1fdb9ba221d0d5396814bfcaf9521f43fd8927fd'
29
+ * - computeHMACSignature('\ud83d\ude00', 'test_secret') => '837da296d05c4fe31f61d5d7ead035099d9585a5bcde87de952012a78f0b0c43
30
+ */
31
+ computeHMACSignatureAsync(payload, secret) {
32
+ throw new Error('computeHMACSignatureAsync not implemented.');
33
+ }
19
34
  }
20
35
 
21
36
  module.exports = CryptoProvider;
@@ -15,6 +15,12 @@ class NodeCryptoProvider extends CryptoProvider {
15
15
  .update(payload, 'utf8')
16
16
  .digest('hex');
17
17
  }
18
+
19
+ /** @override */
20
+ async computeHMACSignatureAsync(payload, secret) {
21
+ const signature = await this.computeHMACSignature(payload, secret);
22
+ return signature;
23
+ }
18
24
  }
19
25
 
20
26
  module.exports = NodeCryptoProvider;
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ const CryptoProvider = require('./CryptoProvider');
4
+
5
+ /**
6
+ * `CryptoProvider which uses the SubtleCrypto interface of the Web Crypto API.
7
+ *
8
+ * This only supports asynchronous operations.
9
+ */
10
+ class SubtleCryptoProvider extends CryptoProvider {
11
+ constructor(subtleCrypto) {
12
+ super();
13
+
14
+ // If no subtle crypto is interface, default to the global namespace. This
15
+ // is to allow custom interfaces (eg. using the Node webcrypto interface in
16
+ // tests).
17
+ this.subtleCrypto = subtleCrypto || crypto.subtle;
18
+ }
19
+
20
+ /** @override */
21
+ computeHMACSignature(payload, secret) {
22
+ throw new Error(
23
+ 'SubtleCryptoProvider cannot be used in a synchronous context.'
24
+ );
25
+ }
26
+
27
+ /** @override */
28
+ async computeHMACSignatureAsync(payload, secret) {
29
+ const encoder = new TextEncoder('utf-8');
30
+
31
+ const key = await this.subtleCrypto.importKey(
32
+ 'raw',
33
+ encoder.encode(secret),
34
+ {
35
+ name: 'HMAC',
36
+ hash: {name: 'SHA-256'},
37
+ },
38
+ false,
39
+ ['sign']
40
+ );
41
+
42
+ const signatureBuffer = await this.subtleCrypto.sign(
43
+ 'hmac',
44
+ key,
45
+ encoder.encode(payload)
46
+ );
47
+
48
+ // crypto.subtle returns the signature in base64 format. This must be
49
+ // encoded in hex to match the CryptoProvider contract. We map each byte in
50
+ // the buffer to its corresponding hex octet and then combine into a string.
51
+ const signatureBytes = new Uint8Array(signatureBuffer);
52
+ const signatureHexCodes = new Array(signatureBytes.length);
53
+
54
+ for (let i = 0; i < signatureBytes.length; i++) {
55
+ signatureHexCodes[i] = byteHexMapping[signatureBytes[i]];
56
+ }
57
+
58
+ return signatureHexCodes.join('');
59
+ }
60
+ }
61
+
62
+ // Cached mapping of byte to hex representation. We do this once to avoid re-
63
+ // computing every time we need to convert the result of a signature to hex.
64
+ const byteHexMapping = new Array(256);
65
+ for (let i = 0; i < byteHexMapping.length; i++) {
66
+ byteHexMapping[i] = i.toString(16).padStart(2, '0');
67
+ }
68
+
69
+ module.exports = SubtleCryptoProvider;
@@ -97,7 +97,7 @@ class NodeHttpClientResponse extends HttpClientResponse {
97
97
 
98
98
  toStream(streamCompleteCallback) {
99
99
  // The raw response is itself the stream, so we just return that. To be
100
- // backwards comaptible, we should invoke the streamCompleteCallback only
100
+ // backwards compatible, we should invoke the streamCompleteCallback only
101
101
  // once the stream has been fully consumed.
102
102
  this._res.once('end', () => streamCompleteCallback());
103
103
  return this._res;
@@ -24,6 +24,11 @@ module.exports = StripeResource.extend({
24
24
  methodType: 'list',
25
25
  }),
26
26
 
27
+ expire: stripeMethod({
28
+ method: 'POST',
29
+ path: '/{session}/expire',
30
+ }),
31
+
27
32
  listLineItems: stripeMethod({
28
33
  method: 'GET',
29
34
  path: '/{session}/line_items',
@@ -0,0 +1,31 @@
1
+ // File generated from our OpenAPI spec
2
+
3
+ 'use strict';
4
+
5
+ const StripeResource = require('../StripeResource');
6
+ const stripeMethod = StripeResource.method;
7
+
8
+ module.exports = StripeResource.extend({
9
+ path: 'shipping_rates',
10
+
11
+ create: stripeMethod({
12
+ method: 'POST',
13
+ path: '',
14
+ }),
15
+
16
+ retrieve: stripeMethod({
17
+ method: 'GET',
18
+ path: '/{shippingRateToken}',
19
+ }),
20
+
21
+ update: stripeMethod({
22
+ method: 'POST',
23
+ path: '/{shippingRateToken}',
24
+ }),
25
+
26
+ list: stripeMethod({
27
+ method: 'GET',
28
+ path: '',
29
+ methodType: 'list',
30
+ }),
31
+ });
package/lib/resources.js CHANGED
@@ -43,6 +43,7 @@ module.exports = {
43
43
  Reviews: require('./resources/Reviews'),
44
44
  SetupAttempts: require('./resources/SetupAttempts'),
45
45
  SetupIntents: require('./resources/SetupIntents'),
46
+ ShippingRates: require('./resources/ShippingRates'),
46
47
  Skus: require('./resources/SKUs'),
47
48
  Sources: require('./resources/Sources'),
48
49
  Subscriptions: require('./resources/Subscriptions'),
package/lib/stripe.js CHANGED
@@ -154,6 +154,28 @@ Stripe.createFetchHttpClient = (fetchFn) => {
154
154
  return new FetchHttpClient(fetchFn);
155
155
  };
156
156
 
157
+ /**
158
+ * Create a CryptoProvider which uses the built-in Node crypto libraries for
159
+ * its crypto operations.
160
+ */
161
+ Stripe.createNodeCryptoProvider = () => {
162
+ const NodeCryptoProvider = require('./crypto/NodeCryptoProvider');
163
+ return new NodeCryptoProvider();
164
+ };
165
+
166
+ /**
167
+ * Creates a CryptoProvider which uses the Subtle Crypto API from the Web
168
+ * Crypto API spec for its crypto operations.
169
+ *
170
+ * A SubtleCrypto interface can optionally be passed in as a parameter. If none
171
+ * is passed, will default to the default `crypto.subtle` object in the global
172
+ * scope.
173
+ */
174
+ Stripe.createSubtleCryptoProvider = (subtleCrypto) => {
175
+ const SubtleCryptoProvider = require('./crypto/SubtleCryptoProvider');
176
+ return new SubtleCryptoProvider(subtleCrypto);
177
+ };
178
+
157
179
  Stripe.prototype = {
158
180
  /**
159
181
  * @deprecated will be removed in a future major version. Use the config object instead:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stripe",
3
- "version": "8.186.0",
3
+ "version": "8.189.0",
4
4
  "description": "Stripe API wrapper",
5
5
  "keywords": [
6
6
  "stripe",
@@ -54,8 +54,8 @@
54
54
  "license": "MIT",
55
55
  "scripts": {
56
56
  "clean": "rm -rf ./.nyc_output ./node_modules/.cache ./coverage",
57
- "mocha": "nyc mocha",
58
- "mocha-only": "mocha",
57
+ "mocha": "nyc mocha --config=test/.mocharc.js",
58
+ "mocha-only": "mocha --config=test/.mocharc.js",
59
59
  "test": "yarn lint && yarn test-typescript && yarn mocha",
60
60
  "test-typescript": "tsc --build types/test",
61
61
  "lint": "eslint --ext .js,.jsx,.ts .",
@@ -1075,7 +1075,7 @@ declare module 'stripe' {
1075
1075
  expand?: Array<string>;
1076
1076
 
1077
1077
  /**
1078
- * A card or bank account to attach to the account for receiving [payouts](https://stripe.com/docs/connect/bank-debit-card-payouts) (you won't be able to use it for top-ups). You can provide either a token, like the ones returned by [Stripe.js](https://stripe.com/docs/stripe-js), or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation.
1078
+ * A card or bank account to attach to the account for receiving [payouts](https://stripe.com/docs/connect/bank-debit-card-payouts) (you won't be able to use it for top-ups). You can provide either a token, like the ones returned by [Stripe.js](https://stripe.com/docs/js), or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation.
1079
1079
  *
1080
1080
  * By default, providing an external account sets it as the new default external account for its currency, and deletes the old default if one exists. To add additional external accounts without replacing the existing default for the currency, use the bank account or card creation API.
1081
1081
  */
@@ -2150,7 +2150,7 @@ declare module 'stripe' {
2150
2150
  expand?: Array<string>;
2151
2151
 
2152
2152
  /**
2153
- * A card or bank account to attach to the account for receiving [payouts](https://stripe.com/docs/connect/bank-debit-card-payouts) (you won't be able to use it for top-ups). You can provide either a token, like the ones returned by [Stripe.js](https://stripe.com/docs/stripe-js), or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation.
2153
+ * A card or bank account to attach to the account for receiving [payouts](https://stripe.com/docs/connect/bank-debit-card-payouts) (you won't be able to use it for top-ups). You can provide either a token, like the ones returned by [Stripe.js](https://stripe.com/docs/js), or a dictionary, as documented in the `external_account` parameter for [bank account](https://stripe.com/docs/api#account_create_bank_account) creation.
2154
2154
  *
2155
2155
  * By default, providing an external account sets it as the new default external account for its currency, and deletes the old default if one exists. To add additional external accounts without replacing the existing default for the currency, use the bank account or card creation API.
2156
2156
  */
@@ -1128,7 +1128,7 @@ declare module 'stripe' {
1128
1128
  account_holder_type: Fpx.AccountHolderType | null;
1129
1129
 
1130
1130
  /**
1131
- * The customer's bank. Can be one of `affin_bank`, `alliance_bank`, `ambank`, `bank_islam`, `bank_muamalat`, `bank_rakyat`, `bsn`, `cimb`, `hong_leong_bank`, `hsbc`, `kfh`, `maybank2u`, `ocbc`, `public_bank`, `rhb`, `standard_chartered`, `uob`, `deutsche_bank`, `maybank2e`, or `pb_enterprise`.
1131
+ * The customer's bank. Can be one of `affin_bank`, `agrobank`, `alliance_bank`, `ambank`, `bank_islam`, `bank_muamalat`, `bank_rakyat`, `bsn`, `cimb`, `hong_leong_bank`, `hsbc`, `kfh`, `maybank2u`, `ocbc`, `public_bank`, `rhb`, `standard_chartered`, `uob`, `deutsche_bank`, `maybank2e`, or `pb_enterprise`.
1132
1132
  */
1133
1133
  bank: Fpx.Bank;
1134
1134
 
@@ -1143,6 +1143,7 @@ declare module 'stripe' {
1143
1143
 
1144
1144
  type Bank =
1145
1145
  | 'affin_bank'
1146
+ | 'agrobank'
1146
1147
  | 'alliance_bank'
1147
1148
  | 'ambank'
1148
1149
  | 'bank_islam'
@@ -1667,7 +1668,7 @@ declare module 'stripe' {
1667
1668
  application_fee_amount?: number;
1668
1669
 
1669
1670
  /**
1670
- * Whether to immediately capture the charge. Defaults to `true`. When `false`, the charge issues an authorization (or pre-authorization), and will need to be [captured](https://stripe.com/docs/api#capture_charge) later. Uncaptured charges expire in _seven days_. For more information, see the [authorizing charges and settling later](https://stripe.com/docs/charges/placing-a-hold) documentation.
1671
+ * Whether to immediately capture the charge. Defaults to `true`. When `false`, the charge issues an authorization (or pre-authorization), and will need to be [captured](https://stripe.com/docs/api#capture_charge) later. Uncaptured charges expire after a set number of days (7 by default). For more information, see the [authorizing charges and settling later](https://stripe.com/docs/charges/placing-a-hold) documentation.
1671
1672
  */
1672
1673
  capture?: boolean;
1673
1674
 
@@ -2017,7 +2018,7 @@ declare module 'stripe' {
2017
2018
  /**
2018
2019
  * Capture the payment of an existing, uncaptured, charge. This is the second half of the two-step payment flow, where first you [created a charge](https://stripe.com/docs/api#create_charge) with the capture option set to false.
2019
2020
  *
2020
- * Uncaptured payments expire exactly seven days after they are created. If they are not captured by that point in time, they will be marked as refunded and will no longer be capturable.
2021
+ * Uncaptured payments expire a set number of days after they are created ([7 by default](https://stripe.com/docs/charges/placing-a-hold)). If they are not captured by that point in time, they will be marked as refunded and will no longer be capturable.
2021
2022
  */
2022
2023
  capture(
2023
2024
  id: string,