@amos.com/react-amos-js 0.10.6 → 0.11.1
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/README.md +65 -75
- package/dist/index.d.ts +40 -14
- package/dist/index.js +1 -1
- package/dist/index.mjs +92 -84
- package/package.json +8 -8
- package/src/index.tsx +74 -37
package/README.md
CHANGED
|
@@ -15,8 +15,8 @@ npm install @amos.com/react-amos-js @amos.com/node
|
|
|
15
15
|
## What it gives you
|
|
16
16
|
|
|
17
17
|
- React components for the iframe payment method forms: `AmosCreditCardPaymentMethodForm`, `AmosBankAccountPaymentMethodForm`, `AmosGooglePayButton`, `AmosApplePayButton`.
|
|
18
|
-
- React-flavoured iframe message helpers that accept a React `ref`: `validateForm({ iframeRef })`, `
|
|
19
|
-
- Re-exports of the `@amos.com/amos-js` helpers and types that come up in client code: `createMessage`, `decodeJwt`, `getEmbedOrigin`, `formatGooglePayPaymentData`, `resetForm`, `ConfirmationResult`, `ConfirmationIncompleteReason`, `FormattedGooglePayPaymentData`, `Appearance`, `Message`, etc.
|
|
18
|
+
- React-flavoured iframe message helpers that accept a React `ref`: `validateForm({ iframeRef })`, `confirmPayment({ iframeRef, token })`, `confirmSetup({ iframeRef, token })`, `resetForm({ iframeRef })`.
|
|
19
|
+
- Re-exports of the `@amos.com/amos-js` helpers and types that come up in client code: `createMessage`, `decodeJwt`, `getEmbedOrigin`, `formatGooglePayPaymentData`, `resetForm`, `ConfirmResult`, `ConfirmationResult`, `ConfirmationIncompleteReason`, `FormattedGooglePayPaymentData`, `Appearance`, `Message`, etc.
|
|
20
20
|
|
|
21
21
|
> **Note:** `@amos.com/react-amos-js` is the client-side half of the Amos integration. For end-to-end payment processing you also need `@amos.com/node` on your server (creating payment intents, handling webhooks, etc.). The same `@amos.com/node` package is listed as a peer dependency so you can import its OpenAPI types in client-side TypeScript code.
|
|
22
22
|
|
|
@@ -39,12 +39,12 @@ The render token configures the iframe's allowed origin(s), allowed payment meth
|
|
|
39
39
|
The following flow is for credit card and bank account payment method types only.
|
|
40
40
|
|
|
41
41
|
1. **Set up prerequisites**: create a `renderToken` (safe for client), and keep `apiKey` and `accountId` server-side only.
|
|
42
|
-
2. **Render your checkout UI** with one of the payment method components (e.g. `AmosCreditCardPaymentMethodForm`)
|
|
42
|
+
2. **Render your checkout UI** with one of the payment method components (e.g. `AmosCreditCardPaymentMethodForm`). Card and bank forms show a field-shaped skeleton immediately (sized from `appearance`, `additionalFields`, and `billingAddressRequirement`); Google Pay and Apple Pay paint a button-shaped skeleton in the parent document on first render so the 48px slot is reserved before the iframe loads.
|
|
43
43
|
3. **User clicks "Pay now" button**: call `validateForm({ iframeRef })`, which returns `Promise<true>` if the embedded form is valid and `Promise<false>` otherwise.
|
|
44
44
|
4. **Create payment intent on your server**: use your server-side Amos client to call `POST /payment_intents`. You may also associate this payment intent with a new or existing customer via `POST /customers`. This must be server-side because it uses your private API key.
|
|
45
45
|
5. **Return the payment intent token to the browser**: your backend responds with the embed token (`components["schemas"]["EmbedToken"]`) needed for confirmation.
|
|
46
|
-
6. **Confirm the payment intent from the client**:
|
|
47
|
-
7. **Handle UX**: show the user a "processing" state
|
|
46
|
+
6. **Confirm the payment intent from the client**: `await confirmPayment({ iframeRef, token })`. Deprecated alias: `confirmPaymentIntent`.
|
|
47
|
+
7. **Handle UX**: show the user a "processing" state while awaiting `confirmPayment`. Do not treat `{ status: "succeeded" }` as settlement proof — verify payment success on your backend via webhooks. Recoverable field errors stay in the iframe; `confirmPayment` still resolves `{ status: "failed" }`. Legacy hosts can keep optional `onResult`.
|
|
48
48
|
|
|
49
49
|
### Google Pay & Apple Pay
|
|
50
50
|
|
|
@@ -52,17 +52,17 @@ Google Pay and Apple Pay are forms of express checkout. Their buttons are altern
|
|
|
52
52
|
|
|
53
53
|
The key differences between the express and non-express payment flows are:
|
|
54
54
|
|
|
55
|
-
- The express payment method components accept
|
|
55
|
+
- The express payment method components accept `onConfirm`. Create a payment intent, then `await confirmPayment(token)`.
|
|
56
56
|
- You do not call `validateForm` in an express flow.
|
|
57
|
-
- You
|
|
57
|
+
- You call `confirmPayment` inside `onConfirm` (the SDK no longer auto-confirms).
|
|
58
58
|
|
|
59
59
|
## Understanding the flow for creating and confirming setup intents
|
|
60
60
|
|
|
61
61
|
Setup intents are used to save payment methods for future use (e.g. recurring payments, subscriptions) without charging the customer immediately. The flow is identical to a payment intent, except:
|
|
62
62
|
|
|
63
63
|
- On the server, call `POST /setup_intents` instead of `POST /payment_intents`.
|
|
64
|
-
- On the client,
|
|
65
|
-
-
|
|
64
|
+
- On the client, `await confirmSetup({ iframeRef, token })` instead of `confirmPayment({ iframeRef, token })`. Deprecated alias: `confirmSetupIntent`.
|
|
65
|
+
- Both resolve `{ status: "succeeded" | "failed" }`.
|
|
66
66
|
|
|
67
67
|
The same `AmosCreditCardPaymentMethodForm` / `AmosBankAccountPaymentMethodForm` components support both payment intents and setup intents — they are differentiated by which confirmation function you call. For bank setup, pass `intent="setup"` so Connect / Plaid is always shown (no merchant ACH threshold lookup).
|
|
68
68
|
|
|
@@ -75,8 +75,8 @@ Why this matters:
|
|
|
75
75
|
- The payment method UI is rendered inside Amos-hosted iframes, so sensitive input fields are not part of your DOM.
|
|
76
76
|
- Raw payment details are submitted from the iframe directly to Amos-controlled infrastructure.
|
|
77
77
|
- Your backend only creates payment intents (or setup intents) and returns a short-lived token used to continue the iframe flow.
|
|
78
|
-
- `
|
|
79
|
-
- In express flows (Google Pay / Apple Pay), the iframe
|
|
78
|
+
- `confirmPayment` / `confirmSetup` send the token back to the iframe to complete confirmation; they do not pass full payment method payloads through your app server.
|
|
79
|
+
- In express flows (Google Pay / Apple Pay), the iframe handles payment data exchange and calls `onConfirm` so your server can create a payment intent token, then you `await confirmPayment(token)`.
|
|
80
80
|
|
|
81
81
|
In short, your app orchestrates the payment flow, while sensitive payment data stays within Amos-controlled components and APIs.
|
|
82
82
|
|
|
@@ -94,10 +94,6 @@ Card and bank components accept an optional `appearance` prop that controls the
|
|
|
94
94
|
"--radius": "0.25rem",
|
|
95
95
|
},
|
|
96
96
|
}}
|
|
97
|
-
onResult={(result) => {
|
|
98
|
-
if (result.status === "failed") setError(result.errorMessage);
|
|
99
|
-
if (result.status === "incomplete") setError(null);
|
|
100
|
-
}}
|
|
101
97
|
/>
|
|
102
98
|
```
|
|
103
99
|
|
|
@@ -167,7 +163,7 @@ Radio groups (e.g. account type) always use an above-style group label regardles
|
|
|
167
163
|
import { useRef, useState } from "react";
|
|
168
164
|
import {
|
|
169
165
|
AmosCreditCardPaymentMethodForm,
|
|
170
|
-
|
|
166
|
+
confirmPayment,
|
|
171
167
|
validateForm,
|
|
172
168
|
} from "@amos.com/react-amos-js";
|
|
173
169
|
import type { components } from "@amos.com/node";
|
|
@@ -212,7 +208,10 @@ function CheckoutForm() {
|
|
|
212
208
|
}
|
|
213
209
|
|
|
214
210
|
const { token } = await response.json();
|
|
215
|
-
|
|
211
|
+
const result = await confirmPayment({ iframeRef, token });
|
|
212
|
+
if (result.status !== "succeeded") {
|
|
213
|
+
setError("Payment failed. Please try again.");
|
|
214
|
+
}
|
|
216
215
|
} catch (error) {
|
|
217
216
|
setError(error instanceof Error ? error.message : "Unknown error");
|
|
218
217
|
} finally {
|
|
@@ -227,16 +226,6 @@ function CheckoutForm() {
|
|
|
227
226
|
renderToken="the-render-token-that-you-created-on-dashboard.amos.com"
|
|
228
227
|
additionalFields={{ cardholderName: true }}
|
|
229
228
|
onValidityChange={({ isValid }) => setIsValid(isValid)}
|
|
230
|
-
onResult={(result) => {
|
|
231
|
-
// Unlock UI. Verify settlement on your backend via webhooks.
|
|
232
|
-
if (result.status === "succeeded") {
|
|
233
|
-
console.log("Confirm returned:", result);
|
|
234
|
-
} else if (result.status === "failed") {
|
|
235
|
-
console.error("Confirm failed:", result.errorMessage);
|
|
236
|
-
} else if (result.status === "incomplete") {
|
|
237
|
-
console.log("Recoverable:", result.reason);
|
|
238
|
-
}
|
|
239
|
-
}}
|
|
240
229
|
/>
|
|
241
230
|
{error ? <p>{error}</p> : null}
|
|
242
231
|
<button type="submit" disabled={!isValid || isProcessing}>
|
|
@@ -254,7 +243,7 @@ import { useState } from "react";
|
|
|
254
243
|
import {
|
|
255
244
|
AmosApplePayButton,
|
|
256
245
|
AmosGooglePayButton,
|
|
257
|
-
type
|
|
246
|
+
type ConfirmResult,
|
|
258
247
|
} from "@amos.com/react-amos-js";
|
|
259
248
|
import type { components } from "@amos.com/node";
|
|
260
249
|
|
|
@@ -283,13 +272,28 @@ async function createPaymentIntentToken({
|
|
|
283
272
|
function CheckoutWallets({ renderToken }: { renderToken: string }) {
|
|
284
273
|
const [error, setError] = useState<string | null>(null);
|
|
285
274
|
|
|
286
|
-
function
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
275
|
+
async function handleConfirm({
|
|
276
|
+
paymentIntentCreateAttributes,
|
|
277
|
+
customerCreateAttributes,
|
|
278
|
+
confirmPayment,
|
|
279
|
+
}: {
|
|
280
|
+
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
281
|
+
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
282
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
283
|
+
}): Promise<ConfirmResult> {
|
|
284
|
+
try {
|
|
285
|
+
const token = await createPaymentIntentToken({
|
|
286
|
+
paymentIntentCreateAttributes,
|
|
287
|
+
customerCreateAttributes,
|
|
288
|
+
});
|
|
289
|
+
const result = await confirmPayment(token);
|
|
290
|
+
if (result.status === "failed") {
|
|
291
|
+
setError("Payment failed. Please try again.");
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
setError(error instanceof Error ? error.message : "Unknown error");
|
|
296
|
+
return { status: "failed" };
|
|
293
297
|
}
|
|
294
298
|
}
|
|
295
299
|
|
|
@@ -301,8 +305,7 @@ function CheckoutWallets({ renderToken }: { renderToken: string }) {
|
|
|
301
305
|
renderToken={renderToken}
|
|
302
306
|
amount="50.00"
|
|
303
307
|
merchantName="Example Store"
|
|
304
|
-
|
|
305
|
-
onResult={handleResult}
|
|
308
|
+
onConfirm={handleConfirm}
|
|
306
309
|
/>
|
|
307
310
|
</div>
|
|
308
311
|
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
|
@@ -310,8 +313,7 @@ function CheckoutWallets({ renderToken }: { renderToken: string }) {
|
|
|
310
313
|
renderToken={renderToken}
|
|
311
314
|
amount="50.00"
|
|
312
315
|
merchantName="Example Store"
|
|
313
|
-
|
|
314
|
-
onResult={handleResult}
|
|
316
|
+
onConfirm={handleConfirm}
|
|
315
317
|
/>
|
|
316
318
|
</div>
|
|
317
319
|
</div>
|
|
@@ -321,7 +323,7 @@ function CheckoutWallets({ renderToken }: { renderToken: string }) {
|
|
|
321
323
|
}
|
|
322
324
|
```
|
|
323
325
|
|
|
324
|
-
Do not call `validateForm`
|
|
326
|
+
Do not call `validateForm` from the host in an express flow — create a payment intent inside `onConfirm`, then `await confirmPayment(token)`. Size the mount slot; omitted `buttonProps` keep paint defaults and fill the iframe.
|
|
325
327
|
|
|
326
328
|
On Safari, Apple Pay uses the native payment sheet. On other browsers, Apple's QR handoff opens in a popup (`pay.apple.com`); while that popup is open, the SDK shows a waiting overlay with **Cancel payment**.
|
|
327
329
|
|
|
@@ -335,8 +337,7 @@ Optional visuals:
|
|
|
335
337
|
height="48px"
|
|
336
338
|
buttonProps={{ buttonType: "donate", buttonBorderType: "no_border" }}
|
|
337
339
|
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
338
|
-
|
|
339
|
-
onResult={handleResult}
|
|
340
|
+
onConfirm={handleConfirm}
|
|
340
341
|
/>
|
|
341
342
|
|
|
342
343
|
<AmosApplePayButton
|
|
@@ -346,8 +347,7 @@ Optional visuals:
|
|
|
346
347
|
height="48px"
|
|
347
348
|
buttonProps={{ type: "donate" }}
|
|
348
349
|
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
349
|
-
|
|
350
|
-
onResult={handleResult}
|
|
350
|
+
onConfirm={handleConfirm}
|
|
351
351
|
/>
|
|
352
352
|
```
|
|
353
353
|
|
|
@@ -357,7 +357,7 @@ Optional visuals:
|
|
|
357
357
|
import { useRef, useState } from "react";
|
|
358
358
|
import {
|
|
359
359
|
AmosCreditCardPaymentMethodForm,
|
|
360
|
-
|
|
360
|
+
confirmSetup,
|
|
361
361
|
validateForm,
|
|
362
362
|
} from "@amos.com/react-amos-js";
|
|
363
363
|
|
|
@@ -393,7 +393,10 @@ function SavePaymentMethodForm() {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
const { token } = await response.json();
|
|
396
|
-
|
|
396
|
+
const result = await confirmSetup({ iframeRef, token });
|
|
397
|
+
if (result.status !== "succeeded") {
|
|
398
|
+
setError("Failed to save the payment method.");
|
|
399
|
+
}
|
|
397
400
|
} catch (error) {
|
|
398
401
|
setError(error instanceof Error ? error.message : "Unknown error");
|
|
399
402
|
} finally {
|
|
@@ -406,15 +409,6 @@ function SavePaymentMethodForm() {
|
|
|
406
409
|
<AmosCreditCardPaymentMethodForm
|
|
407
410
|
ref={iframeRef}
|
|
408
411
|
renderToken="the-render-token-that-you-created-on-dashboard.amos.com"
|
|
409
|
-
onResult={(result) => {
|
|
410
|
-
if (result.status === "succeeded") {
|
|
411
|
-
console.log("Confirm returned:", result);
|
|
412
|
-
} else if (result.status === "failed") {
|
|
413
|
-
console.error("Confirm failed:", result.errorMessage);
|
|
414
|
-
} else if (result.status === "incomplete") {
|
|
415
|
-
console.log("Recoverable:", result.reason);
|
|
416
|
-
}
|
|
417
|
-
}}
|
|
418
412
|
/>
|
|
419
413
|
{error ? <p>{error}</p> : null}
|
|
420
414
|
<button type="submit" disabled={isProcessing}>
|
|
@@ -437,31 +431,31 @@ Validates the embedded card/bank iframe form before payment confirmation.
|
|
|
437
431
|
|
|
438
432
|
**Returns:** `Promise<boolean>` (resolves to `false` after 5 seconds if the iframe does not respond).
|
|
439
433
|
|
|
440
|
-
### `
|
|
434
|
+
### `confirmPayment({ iframeRef, token })`
|
|
441
435
|
|
|
442
|
-
Confirms a payment intent in the embedded iframe flow.
|
|
436
|
+
Confirms a payment intent in the embedded iframe flow. Resolves `{ status: "succeeded" }` or `{ status: "failed" }`. Deprecated alias: `confirmPaymentIntent`.
|
|
443
437
|
|
|
444
438
|
**Parameters:**
|
|
445
439
|
|
|
446
440
|
- `iframeRef` (`React.RefObject<HTMLIFrameElement | null> | undefined`, required)
|
|
447
441
|
- `token` (typed as `Pick<components["schemas"]["EmbedToken"], "token">` — the embed JWT string returned by your server)
|
|
448
442
|
|
|
449
|
-
**Returns:** `
|
|
443
|
+
**Returns:** `Promise<ConfirmResult>`
|
|
450
444
|
|
|
451
|
-
### `
|
|
445
|
+
### `confirmSetup({ iframeRef, token })`
|
|
452
446
|
|
|
453
|
-
Confirms a setup intent in the embedded iframe flow. Use this when saving a payment method for future use.
|
|
447
|
+
Confirms a setup intent in the embedded iframe flow. Use this when saving a payment method for future use. Deprecated alias: `confirmSetupIntent`.
|
|
454
448
|
|
|
455
449
|
**Parameters:**
|
|
456
450
|
|
|
457
451
|
- `iframeRef` (`React.RefObject<HTMLIFrameElement | null> | undefined`, required)
|
|
458
452
|
- `token` (same `Pick<components["schemas"]["EmbedToken"], "token">` embed JWT string as for payment confirmation)
|
|
459
453
|
|
|
460
|
-
**Returns:** `
|
|
454
|
+
**Returns:** `Promise<ConfirmResult>`
|
|
461
455
|
|
|
462
456
|
### `resetForm({ iframeRef })`
|
|
463
457
|
|
|
464
|
-
Clears all field values and API errors in the embedded card/bank iframe form. Call after
|
|
458
|
+
Clears all field values and API errors in the embedded card/bank iframe form. Call after a failed or incomplete confirm when the customer wants to try again (for example, after a successful payment when starting a new one).
|
|
465
459
|
|
|
466
460
|
**Parameters:**
|
|
467
461
|
|
|
@@ -476,7 +470,6 @@ Renders the secure credit card iframe form. A field-shaped skeleton is shown imm
|
|
|
476
470
|
**Required props:**
|
|
477
471
|
|
|
478
472
|
- `renderToken` (`string`)
|
|
479
|
-
- `onResult` (`(result: ConfirmationResult) => void`) — required. Called when the interactive confirmation attempt finishes (`succeeded`, `failed`, or `incomplete` with `reason`). Not settlement proof; verify via webhooks.
|
|
480
473
|
|
|
481
474
|
**Optional props:**
|
|
482
475
|
|
|
@@ -484,6 +477,7 @@ Renders the secure credit card iframe form. A field-shaped skeleton is shown imm
|
|
|
484
477
|
|
|
485
478
|
- `additionalFields` (`{ cardholderName: boolean }`) — set `additionalFields={{ cardholderName: true }}` to render the cardholder name field in the iframe (`false` by default)
|
|
486
479
|
- `billingAddressRequirement` (`"country" | "full"`, defaults to `"country"`) — how much billing address the iframe collects. `country` collects country / region and, for CA / PR / GB / US, a postal code (labeled ZIP for the United States). `full` shows a full street address form with Smarty autocomplete.
|
|
480
|
+
- `onResult` (`(result: ConfirmationResult) => void`) — **deprecated.** Prefer `await confirmPayment()` / `await confirmSetup()`. Still fired for existing hosts (`succeeded`, `failed`, or `incomplete` with `reason`). Not settlement proof; verify via webhooks.
|
|
487
481
|
- `onValidityChange` (`(event: { isValid: boolean }) => void`) — called when form validity changes. `isValid` is true when all required fields are present and valid. Does not include PCI data. Use this to enable or disable your checkout button.
|
|
488
482
|
- `onCardBrandChanged` (`(event: { brand: CardBrand | null }) => void`) — called when the detected card brand changes. `brand` is `"visa"`, `"mastercard"`, `"amex"`, `"discover"`, `"diners"`, or `"jcb"`, or `null` when the field is empty or the number does not match a known brand. Does not include PCI data.
|
|
489
483
|
|
|
@@ -495,7 +489,7 @@ Renders the secure bank account iframe form. A field-shaped skeleton is shown im
|
|
|
495
489
|
|
|
496
490
|
When the charge meets the merchant’s ACH verification threshold, the SDK hides the routing/account iframe and renders a **Connect bank account** button in the parent page. The button follows the same outline/focus defaults as Amos UI (`--ring`, `--border`, `--radius`, `--input-height`, …): it inherits those CSS variables from the host page when present, and `appearance.themeVariables` overrides them the same way as the iframe. Clicking it asks the iframe to mint a Plaid Link token, then opens [Plaid Link](https://plaid.com/docs/link/web/). Hosts do not proxy Pay API (`GET /merchants`, `POST /plaid_link_tokens`); embed does that with `PAY_API_KEY`. Do not put Plaid secrets in the browser.
|
|
497
491
|
|
|
498
|
-
**Required props:** same as `AmosCreditCardPaymentMethodForm` — `renderToken
|
|
492
|
+
**Required props:** same as `AmosCreditCardPaymentMethodForm` — `renderToken` — plus:
|
|
499
493
|
|
|
500
494
|
- `amount` (`string`, major-currency decimal, e.g. `"50.00"`, defaults to `"0"`) — same format as Google Pay / Apple Pay. Compared to the threshold the iframe fetches (cents). Pass `"0"` (the default) on open-amount forms until the customer enters a charge — 0 is typically under the threshold, so Connect stays hidden. Pass a new `amount` when the customer changes the charge.
|
|
501
495
|
- `intent` (`"payment" | "setup"`, defaults to `"payment"`) — `"setup"` always shows Connect / Plaid (no merchant ACH threshold lookup), unless the render token disables verification. Use this when saving a bank account for later charges.
|
|
@@ -508,7 +502,6 @@ Compare locally once the iframe posts `ACH_THRESHOLD`: Plaid when `requireVerifi
|
|
|
508
502
|
<AmosBankAccountPaymentMethodForm
|
|
509
503
|
renderToken={renderToken}
|
|
510
504
|
amount="50.00" // defaults to "0" (manual form until the charge meets the threshold)
|
|
511
|
-
onResult={onResult}
|
|
512
505
|
/>
|
|
513
506
|
```
|
|
514
507
|
|
|
@@ -518,11 +511,10 @@ Setup (always Connect, no merchant lookup):
|
|
|
518
511
|
<AmosBankAccountPaymentMethodForm
|
|
519
512
|
renderToken={renderToken}
|
|
520
513
|
intent="setup"
|
|
521
|
-
onResult={onResult}
|
|
522
514
|
/>
|
|
523
515
|
```
|
|
524
516
|
|
|
525
|
-
`validateForm` / `
|
|
517
|
+
`validateForm` / `confirmPayment` / `confirmSetup` stay iframe-based. When Plaid succeeded, confirm sends `payment_method.plaid` (`public_token`, `account_id`) and does not require typed account numbers.
|
|
526
518
|
|
|
527
519
|
**CSP:** the parent page must allow Plaid’s script and frames, for example `script-src https://cdn.plaid.com` and `frame-src https://cdn.plaid.com https://*.plaid.com`. Amos never loads `PLAID_SECRET` / `PLAID_CLIENT_ID` in the SDK or embed iframe.
|
|
528
520
|
|
|
@@ -537,9 +529,7 @@ Renders the secure Google Pay iframe button (express checkout flow). A button-sh
|
|
|
537
529
|
- `renderToken` (`string`)
|
|
538
530
|
- `amount` (`string`) — major-currency decimal string shown in the wallet sheet (e.g. `"50.00"` for $50.00). The iframe converts this to cents in `paymentIntentCreateAttributes.amount`.
|
|
539
531
|
- `merchantName` (`string`)
|
|
540
|
-
- `
|
|
541
|
-
|
|
542
|
-
- `onResult` (`(result: ConfirmationResult) => void`) — required. Called when the interactive confirmation attempt finishes (`succeeded`, `failed`, or `incomplete` with `reason`). Not settlement proof; verify via webhooks.
|
|
532
|
+
- `onConfirm` (callback receiving `{ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment }`. Create a payment intent, then `return confirmPayment(token)` — `Promise<ConfirmResult>`)
|
|
543
533
|
|
|
544
534
|
**Optional props:**
|
|
545
535
|
|
|
@@ -595,14 +585,14 @@ Re-exports of the same advanced helpers exposed by `@amos.com/amos-js`. Most int
|
|
|
595
585
|
|
|
596
586
|
### Exported types
|
|
597
587
|
|
|
598
|
-
`@amos.com/react-amos-js` re-exports everything from `@amos.com/amos-js`, including `
|
|
588
|
+
`@amos.com/react-amos-js` re-exports everything from `@amos.com/amos-js`, including `ConfirmResult`, `ConfirmationResult` (deprecated), `ConfirmationIncompleteReason`, `PaymentMethodFormValidityChangeEvent`, `CardBrand`, `PaymentMethodFormCardBrandChangeEvent`, `FormattedGooglePayPaymentData`, `Message`, `Appearance`, `ThemeVariable`, and the per-form `*Options` / `*Controller` types. For OpenAPI schema types (e.g. `PaymentIntent`, `CreatePaymentIntentInput`), import `components` from `@amos.com/node`.
|
|
599
589
|
|
|
600
590
|
## Notes and potential gotchas
|
|
601
591
|
|
|
602
|
-
- **`ref` / `iframeRef`**: for card and bank forms, pass `ref={iframeRef}` to the form component. The same `iframeRef` must be used when calling `validateForm`, `
|
|
603
|
-
- **`
|
|
604
|
-
- **Same components for payment vs setup intents**: `AmosCreditCardPaymentMethodForm` and `AmosBankAccountPaymentMethodForm` support both payment intents and setup intents. The flow differs only by which server call you make and which confirmation function you use (`
|
|
605
|
-
- **Amount format**: for `AmosGooglePayButton`, `AmosApplePayButton`, and `AmosBankAccountPaymentMethodForm`, `amount` is a major-currency decimal string (e.g. `"50.00"` for $50.00). For `components["schemas"]["CreatePaymentIntentInput"]` on the server (card/bank create, and the object the wallet iframe sends to `
|
|
592
|
+
- **`ref` / `iframeRef`**: for card and bank forms, pass `ref={iframeRef}` to the form component. The same `iframeRef` must be used when calling `validateForm`, `confirmPayment`, `confirmSetup`, or `resetForm`. The component forwards the ref to the inner iframe.
|
|
593
|
+
- **`confirmPayment` / `confirmSetup` are not settlement proof**: `{ status: "succeeded" }` means authorization succeeded (capture may still finish asynchronously). Verify payment or setup success on your backend via webhooks. Recoverable field errors stay in the iframe; the Promise still resolves `{ status: "failed" }`. Deprecated `onResult` still receives `incomplete` with `reason` (`"field_errors"` or `"validation_failed"`).
|
|
594
|
+
- **Same components for payment vs setup intents**: `AmosCreditCardPaymentMethodForm` and `AmosBankAccountPaymentMethodForm` support both payment intents and setup intents. The flow differs only by which server call you make and which confirmation function you use (`confirmPayment` vs `confirmSetup`).
|
|
595
|
+
- **Amount format**: for `AmosGooglePayButton`, `AmosApplePayButton`, and `AmosBankAccountPaymentMethodForm`, `amount` is a major-currency decimal string (e.g. `"50.00"` for $50.00). For `components["schemas"]["CreatePaymentIntentInput"]` on the server (card/bank create, and the object the wallet iframe sends to `onConfirm`), `amount` is a number in cents (e.g. `5000`).
|
|
606
596
|
- **Plaid Link (ACH verification)**: load `cdn.plaid.com` from the **parent** document (see CSP on `AmosBankAccountPaymentMethodForm`). Merchants do not proxy Pay API; the bank iframe fetches the ACH threshold for payment intents and mints link tokens. Setup intents skip the merchant lookup and always require Plaid unless the render token disables verification. Confirm still goes through the bank iframe so Amos can attach `plaid` to the payment method.
|
|
607
597
|
- **Apple Pay waiting overlay**: on browsers where Apple's QR handoff opens in a popup (non-Safari), `AmosApplePayButton` shows a fixed full-viewport overlay on the host page until payment completes, the popup closes, or the user clicks **Cancel payment**. Avoid stacking other fixed UI above it.
|
|
608
598
|
- **Going framework-free**: if you need to use Amos outside of React (vanilla JS, another framework, etc.), use [`@amos.com/amos-js`](../amos-js) directly.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="googlepay" />
|
|
2
|
-
import { Appearance, ApplePayButtonElementProps, BillingAddressRequirement, ConfirmationResult, CreditCardAdditionalFields, GooglePayButtonElementProps } from '@amos.com/amos-js';
|
|
2
|
+
import { Appearance, ApplePayButtonElementProps, BillingAddressRequirement, ConfirmationResult, ConfirmResult, CreditCardAdditionalFields, GooglePayButtonElementProps } from '@amos.com/amos-js';
|
|
3
3
|
import { components } from '@amos.com/node';
|
|
4
4
|
import { ComponentProps, Ref, RefObject } from 'react';
|
|
5
5
|
export * from '@amos.com/amos-js';
|
|
@@ -20,9 +20,9 @@ export declare function validateForm({ iframeRef, }: {
|
|
|
20
20
|
* Pass the embed JWT (`token`) returned by your server's
|
|
21
21
|
* `POST /payment_intents` call.
|
|
22
22
|
*/
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function confirmPayment({ iframeRef, token, }: {
|
|
24
24
|
iframeRef: IframeRef;
|
|
25
|
-
} & Pick<components["schemas"]["EmbedToken"], "token">):
|
|
25
|
+
} & Pick<components["schemas"]["EmbedToken"], "token">): Promise<ConfirmResult>;
|
|
26
26
|
/**
|
|
27
27
|
* Confirm a setup intent in the embedded iframe flow. Use this when
|
|
28
28
|
* saving a payment method for future use.
|
|
@@ -30,9 +30,21 @@ export declare function confirmPaymentIntent({ iframeRef, token, }: {
|
|
|
30
30
|
* Pass the embed JWT (`token`) returned by your server's
|
|
31
31
|
* `POST /setup_intents` call.
|
|
32
32
|
*/
|
|
33
|
+
export declare function confirmSetup({ iframeRef, token, }: {
|
|
34
|
+
iframeRef: IframeRef;
|
|
35
|
+
} & Pick<components["schemas"]["EmbedToken"], "token">): Promise<ConfirmResult>;
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use {@link confirmPayment}.
|
|
38
|
+
*/
|
|
39
|
+
export declare function confirmPaymentIntent({ iframeRef, token, }: {
|
|
40
|
+
iframeRef: IframeRef;
|
|
41
|
+
} & Pick<components["schemas"]["EmbedToken"], "token">): Promise<ConfirmResult>;
|
|
42
|
+
/**
|
|
43
|
+
* @deprecated Use {@link confirmSetup}.
|
|
44
|
+
*/
|
|
33
45
|
export declare function confirmSetupIntent({ iframeRef, token, }: {
|
|
34
46
|
iframeRef: IframeRef;
|
|
35
|
-
} & Pick<components["schemas"]["EmbedToken"], "token">):
|
|
47
|
+
} & Pick<components["schemas"]["EmbedToken"], "token">): Promise<ConfirmResult>;
|
|
36
48
|
/**
|
|
37
49
|
* Clear all field values and API errors in the embedded card/bank iframe
|
|
38
50
|
* form. Call after `onResult` when the customer wants to try again.
|
|
@@ -45,7 +57,10 @@ type IframePassthroughProps = Omit<ComponentProps<"iframe">, "src" | "title" | "
|
|
|
45
57
|
type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
46
58
|
renderToken: string;
|
|
47
59
|
appearance?: Appearance;
|
|
48
|
-
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated Prefer `await confirmPayment()` / `await confirmSetup()`.
|
|
62
|
+
*/
|
|
63
|
+
onResult?: (result: ConfirmationResult) => void;
|
|
49
64
|
/**
|
|
50
65
|
* Called when form validity changes. `isValid` is true when all
|
|
51
66
|
* required fields are present and valid. Does not include PCI data.
|
|
@@ -68,7 +83,10 @@ export declare function AmosCreditCardPaymentMethodForm({ ref, renderToken, appe
|
|
|
68
83
|
type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
69
84
|
renderToken: string;
|
|
70
85
|
appearance?: Appearance;
|
|
71
|
-
|
|
86
|
+
/**
|
|
87
|
+
* @deprecated Prefer `await confirmPayment()` / `await confirmSetup()`.
|
|
88
|
+
*/
|
|
89
|
+
onResult?: (result: ConfirmationResult) => void;
|
|
72
90
|
/**
|
|
73
91
|
* Called when form validity changes. `isValid` is true when all
|
|
74
92
|
* required fields are present and valid, or when Plaid Link has
|
|
@@ -126,18 +144,22 @@ type AmosGooglePayButtonProps = {
|
|
|
126
144
|
buttonProps?: GooglePayButtonElementProps;
|
|
127
145
|
/** Props applied to the host-page `<iframe>` element. */
|
|
128
146
|
iframeProps?: IframePassthroughProps;
|
|
129
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Called when the buyer authorizes in the Google Pay sheet. Create a
|
|
149
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
150
|
+
*/
|
|
151
|
+
onConfirm: ({ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment, }: {
|
|
130
152
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
131
153
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
155
|
+
}) => Promise<ConfirmResult>;
|
|
134
156
|
};
|
|
135
157
|
/**
|
|
136
158
|
* Renders the secure Google Pay iframe button. A button-shaped
|
|
137
159
|
* skeleton is painted in the parent document on first render (including
|
|
138
160
|
* SSR) so the slot height is reserved before the iframe loads.
|
|
139
161
|
*/
|
|
140
|
-
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps,
|
|
162
|
+
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps, onConfirm, }: AmosGooglePayButtonProps): import("react").JSX.Element;
|
|
141
163
|
type AmosApplePayButtonProps = {
|
|
142
164
|
ref?: ForwardedIframeRef;
|
|
143
165
|
renderToken: string;
|
|
@@ -162,15 +184,19 @@ type AmosApplePayButtonProps = {
|
|
|
162
184
|
buttonProps?: ApplePayButtonElementProps;
|
|
163
185
|
/** Props applied to the host-page `<iframe>` element. */
|
|
164
186
|
iframeProps?: IframePassthroughProps;
|
|
165
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Called when the buyer authorizes in the Apple Pay sheet. Create a
|
|
189
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
190
|
+
*/
|
|
191
|
+
onConfirm: ({ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment, }: {
|
|
166
192
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
167
193
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
168
|
-
|
|
169
|
-
|
|
194
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
195
|
+
}) => Promise<ConfirmResult>;
|
|
170
196
|
};
|
|
171
197
|
/**
|
|
172
198
|
* Renders the secure Apple Pay iframe button. A button-shaped
|
|
173
199
|
* skeleton is painted in the parent document on first render (including
|
|
174
200
|
* SSR) so the slot height is reserved before the iframe loads.
|
|
175
201
|
*/
|
|
176
|
-
export declare function AmosApplePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps,
|
|
202
|
+
export declare function AmosApplePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps, onConfirm, }: AmosApplePayButtonProps): import("react").JSX.Element;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@amos.com/amos-js"),t=require("react"),n=require("react/jsx-runtime");function r(e){return e?e.current??null:null}function i({iframeRef:t}){return(0,e.validateForm)({iframe:r(t)})}function a({iframeRef:t,token:n}){(0,e.
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@amos.com/amos-js"),t=require("react"),n=require("react/jsx-runtime");function r(e){return e?e.current??null:null}function i({iframeRef:t}){return(0,e.validateForm)({iframe:r(t)})}function a({iframeRef:t,token:n}){return(0,e.confirmPayment)({iframe:r(t),token:n})}function o({iframeRef:t,token:n}){return(0,e.confirmSetup)({iframe:r(t),token:n})}function s({iframeRef:t,token:n}){return(0,e.confirmPaymentIntent)({iframe:r(t),token:n})}function c({iframeRef:t,token:n}){return(0,e.confirmSetupIntent)({iframe:r(t),token:n})}function l({iframeRef:t}){(0,e.resetForm)({iframe:r(t)})}function u(e,t){typeof e==`function`?e(t):e&&(e.current=t)}function d(e,{style:t,className:n,id:r,...i}){n!=null&&(e.className=n),r!=null&&(e.id=r),Object.assign(e.style,t);for(let[t,n]of Object.entries(i))n!=null&&(t in e?Reflect.set(e,t,n):e.setAttribute(t,String(n)))}function f({containerRef:e,iframeRef:n,mount:r,options:i,remountDeps:a,iframePassthrough:o,updateDeps:s}){let c=(0,t.useRef)(null);(0,t.useLayoutEffect)(()=>{let t=e.current;if(!t)return;let a=r(t,i);return c.current=a,u(n,a.iframe),d(a.iframe,o),()=>{a.destroy(),c.current=null,u(n,null)}},[...a]),(0,t.useEffect)(()=>{c.current?.update(i)},[...s]),(0,t.useEffect)(()=>{let e=c.current?.iframe;e&&d(e,o)})}var p=`oklch(0.97 0 0)`;function m({height:r,borderRadius:i,containerRef:a}){return(0,t.useLayoutEffect)(()=>{(0,e.ensureSkeletonStyles)()},[]),(0,n.jsxs)(`div`,{style:{boxSizing:`border-box`,position:`relative`,width:`100%`,height:r,minHeight:r,overflow:`hidden`},children:[(0,n.jsx)(`div`,{className:`amos-js-form-skeleton-input amos-js-wallet-skeleton`,style:{position:`absolute`,inset:0,height:r,borderRadius:i,background:p,pointerEvents:`none`,zIndex:0},"aria-hidden":!0}),(0,n.jsx)(`div`,{ref:a,style:{position:`absolute`,inset:0,zIndex:1,width:`100%`,height:`100%`}})]})}function h({ref:r,renderToken:i,appearance:a,onResult:o,onValidityChange:s,onCardBrandChanged:c,additionalFields:l={cardholderName:!1},billingAddressRequirement:u=`country`,style:d,...p}){let m=(0,t.useRef)(null);return f({containerRef:m,iframeRef:r,mount:e.mountAmosCreditCardPaymentMethodForm,options:{renderToken:i,appearance:a,additionalFields:l,billingAddressRequirement:u,onResult:o,onValidityChange:s,onCardBrandChanged:c},remountDeps:[i,l.cardholderName,u],iframePassthrough:{style:d,...p},updateDeps:[a,l,u,o,s,c]}),(0,n.jsx)(`div`,{ref:m})}function g({ref:r,renderToken:i,appearance:a,onResult:o,onValidityChange:s,billingAddressRequirement:c=`country`,amount:l=`0`,intent:u=`payment`,style:d,...p}){let m=(0,t.useRef)(null);return f({containerRef:m,iframeRef:r,mount:e.mountAmosBankAccountPaymentMethodForm,options:{renderToken:i,appearance:a,billingAddressRequirement:c,amount:l,intent:u,onResult:o,onValidityChange:s},remountDeps:[i,c,u],iframePassthrough:{style:d,...p},updateDeps:[a,c,l,u,o,s]}),(0,n.jsx)(`div`,{ref:m})}function _({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onConfirm:u}){let d=(0,t.useRef)(null),p=(0,e.resolveWalletButtonSkeletonBorderRadius)({iframeStyle:l?.style,buttonProps:c});return f({containerRef:d,iframeRef:r,mount:e.mountAmosGooglePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onConfirm:u},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,u]}),(0,n.jsx)(m,{height:s,borderRadius:p,containerRef:d})}function v({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onConfirm:u}){let d=(0,t.useRef)(null),p=(0,e.resolveWalletButtonSkeletonBorderRadius)({iframeStyle:l?.style,buttonProps:c});return f({containerRef:d,iframeRef:r,mount:e.mountAmosApplePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onConfirm:u},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,u]}),(0,n.jsx)(m,{height:s,borderRadius:p,containerRef:d})}exports.AmosApplePayButton=v,exports.AmosBankAccountPaymentMethodForm=g,exports.AmosCreditCardPaymentMethodForm=h,exports.AmosGooglePayButton=_,exports.confirmPayment=a,exports.confirmPaymentIntent=s,exports.confirmSetup=o,exports.confirmSetupIntent=c,exports.resetForm=l,exports.validateForm=i,Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
|
package/dist/index.mjs
CHANGED
|
@@ -1,57 +1,69 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useEffect as
|
|
3
|
-
import { jsx as
|
|
1
|
+
import { confirmPayment as e, confirmPaymentIntent as t, confirmSetup as n, confirmSetupIntent as r, ensureSkeletonStyles as i, mountAmosApplePayButton as a, mountAmosBankAccountPaymentMethodForm as o, mountAmosCreditCardPaymentMethodForm as s, mountAmosGooglePayButton as c, resetForm as l, resolveWalletButtonSkeletonBorderRadius as u, validateForm as d } from "@amos.com/amos-js";
|
|
2
|
+
import { useEffect as f, useLayoutEffect as p, useRef as m } from "react";
|
|
3
|
+
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
4
4
|
export * from "@amos.com/amos-js";
|
|
5
5
|
//#region src/index.tsx
|
|
6
|
-
function
|
|
6
|
+
function _(e) {
|
|
7
7
|
return e ? e.current ?? null : null;
|
|
8
8
|
}
|
|
9
|
-
function
|
|
10
|
-
return
|
|
9
|
+
function v({ iframeRef: e }) {
|
|
10
|
+
return d({ iframe: _(e) });
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
e({
|
|
14
|
-
iframe:
|
|
12
|
+
function y({ iframeRef: t, token: n }) {
|
|
13
|
+
return e({
|
|
14
|
+
iframe: _(t),
|
|
15
15
|
token: n
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
function
|
|
19
|
-
|
|
20
|
-
iframe:
|
|
18
|
+
function b({ iframeRef: e, token: t }) {
|
|
19
|
+
return n({
|
|
20
|
+
iframe: _(e),
|
|
21
|
+
token: t
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function x({ iframeRef: e, token: n }) {
|
|
25
|
+
return t({
|
|
26
|
+
iframe: _(e),
|
|
21
27
|
token: n
|
|
22
28
|
});
|
|
23
29
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
30
|
+
function S({ iframeRef: e, token: t }) {
|
|
31
|
+
return r({
|
|
32
|
+
iframe: _(e),
|
|
33
|
+
token: t
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function C({ iframeRef: e }) {
|
|
37
|
+
l({ iframe: _(e) });
|
|
26
38
|
}
|
|
27
|
-
function
|
|
39
|
+
function w(e, t) {
|
|
28
40
|
typeof e == "function" ? e(t) : e && (e.current = t);
|
|
29
41
|
}
|
|
30
|
-
function
|
|
42
|
+
function T(e, { style: t, className: n, id: r, ...i }) {
|
|
31
43
|
n != null && (e.className = n), r != null && (e.id = r), Object.assign(e.style, t);
|
|
32
44
|
for (let [t, n] of Object.entries(i)) n != null && (t in e ? Reflect.set(e, t, n) : e.setAttribute(t, String(n)));
|
|
33
45
|
}
|
|
34
|
-
function
|
|
35
|
-
let s =
|
|
36
|
-
|
|
46
|
+
function E({ containerRef: e, iframeRef: t, mount: n, options: r, remountDeps: i, iframePassthrough: a, updateDeps: o }) {
|
|
47
|
+
let s = m(null);
|
|
48
|
+
p(() => {
|
|
37
49
|
let i = e.current;
|
|
38
50
|
if (!i) return;
|
|
39
51
|
let o = n(i, r);
|
|
40
|
-
return s.current = o,
|
|
41
|
-
o.destroy(), s.current = null,
|
|
52
|
+
return s.current = o, w(t, o.iframe), T(o.iframe, a), () => {
|
|
53
|
+
o.destroy(), s.current = null, w(t, null);
|
|
42
54
|
};
|
|
43
|
-
}, [...i]),
|
|
55
|
+
}, [...i]), f(() => {
|
|
44
56
|
s.current?.update(r);
|
|
45
|
-
}, [...o]),
|
|
57
|
+
}, [...o]), f(() => {
|
|
46
58
|
let e = s.current?.iframe;
|
|
47
|
-
e &&
|
|
59
|
+
e && T(e, a);
|
|
48
60
|
});
|
|
49
61
|
}
|
|
50
|
-
var
|
|
51
|
-
function
|
|
52
|
-
return
|
|
53
|
-
|
|
54
|
-
}, []), /* @__PURE__ */
|
|
62
|
+
var D = "oklch(0.97 0 0)";
|
|
63
|
+
function O({ height: e, borderRadius: t, containerRef: n }) {
|
|
64
|
+
return p(() => {
|
|
65
|
+
i();
|
|
66
|
+
}, []), /* @__PURE__ */ g("div", {
|
|
55
67
|
style: {
|
|
56
68
|
boxSizing: "border-box",
|
|
57
69
|
position: "relative",
|
|
@@ -60,20 +72,20 @@ function w({ height: e, borderRadius: t, containerRef: r }) {
|
|
|
60
72
|
minHeight: e,
|
|
61
73
|
overflow: "hidden"
|
|
62
74
|
},
|
|
63
|
-
children: [/* @__PURE__ */
|
|
75
|
+
children: [/* @__PURE__ */ h("div", {
|
|
64
76
|
className: "amos-js-form-skeleton-input amos-js-wallet-skeleton",
|
|
65
77
|
style: {
|
|
66
78
|
position: "absolute",
|
|
67
79
|
inset: 0,
|
|
68
80
|
height: e,
|
|
69
81
|
borderRadius: t,
|
|
70
|
-
background:
|
|
82
|
+
background: D,
|
|
71
83
|
pointerEvents: "none",
|
|
72
84
|
zIndex: 0
|
|
73
85
|
},
|
|
74
86
|
"aria-hidden": !0
|
|
75
|
-
}), /* @__PURE__ */
|
|
76
|
-
ref:
|
|
87
|
+
}), /* @__PURE__ */ h("div", {
|
|
88
|
+
ref: n,
|
|
77
89
|
style: {
|
|
78
90
|
position: "absolute",
|
|
79
91
|
inset: 0,
|
|
@@ -84,24 +96,24 @@ function w({ height: e, borderRadius: t, containerRef: r }) {
|
|
|
84
96
|
})]
|
|
85
97
|
});
|
|
86
98
|
}
|
|
87
|
-
function
|
|
88
|
-
let d =
|
|
89
|
-
return
|
|
99
|
+
function k({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChange: i, onCardBrandChanged: a, additionalFields: o = { cardholderName: !1 }, billingAddressRequirement: c = "country", style: l, ...u }) {
|
|
100
|
+
let d = m(null);
|
|
101
|
+
return E({
|
|
90
102
|
containerRef: d,
|
|
91
103
|
iframeRef: e,
|
|
92
|
-
mount:
|
|
104
|
+
mount: s,
|
|
93
105
|
options: {
|
|
94
106
|
renderToken: t,
|
|
95
107
|
appearance: n,
|
|
96
|
-
additionalFields:
|
|
108
|
+
additionalFields: o,
|
|
97
109
|
billingAddressRequirement: c,
|
|
98
110
|
onResult: r,
|
|
99
111
|
onValidityChange: i,
|
|
100
|
-
onCardBrandChanged:
|
|
112
|
+
onCardBrandChanged: a
|
|
101
113
|
},
|
|
102
114
|
remountDeps: [
|
|
103
115
|
t,
|
|
104
|
-
|
|
116
|
+
o.cardholderName,
|
|
105
117
|
c
|
|
106
118
|
],
|
|
107
119
|
iframePassthrough: {
|
|
@@ -110,32 +122,32 @@ function T({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChang
|
|
|
110
122
|
},
|
|
111
123
|
updateDeps: [
|
|
112
124
|
n,
|
|
113
|
-
|
|
125
|
+
o,
|
|
114
126
|
c,
|
|
115
127
|
r,
|
|
116
128
|
i,
|
|
117
|
-
|
|
129
|
+
a
|
|
118
130
|
]
|
|
119
|
-
}), /* @__PURE__ */
|
|
131
|
+
}), /* @__PURE__ */ h("div", { ref: d });
|
|
120
132
|
}
|
|
121
|
-
function
|
|
122
|
-
let d =
|
|
123
|
-
return
|
|
133
|
+
function A({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChange: i, billingAddressRequirement: a = "country", amount: s = "0", intent: c = "payment", style: l, ...u }) {
|
|
134
|
+
let d = m(null);
|
|
135
|
+
return E({
|
|
124
136
|
containerRef: d,
|
|
125
137
|
iframeRef: e,
|
|
126
|
-
mount:
|
|
138
|
+
mount: o,
|
|
127
139
|
options: {
|
|
128
140
|
renderToken: t,
|
|
129
141
|
appearance: n,
|
|
130
|
-
billingAddressRequirement:
|
|
142
|
+
billingAddressRequirement: a,
|
|
131
143
|
amount: s,
|
|
132
144
|
intent: c,
|
|
133
145
|
onResult: r,
|
|
134
|
-
onValidityChange:
|
|
146
|
+
onValidityChange: i
|
|
135
147
|
},
|
|
136
148
|
remountDeps: [
|
|
137
149
|
t,
|
|
138
|
-
|
|
150
|
+
a,
|
|
139
151
|
c
|
|
140
152
|
],
|
|
141
153
|
iframePassthrough: {
|
|
@@ -144,81 +156,77 @@ function E({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChang
|
|
|
144
156
|
},
|
|
145
157
|
updateDeps: [
|
|
146
158
|
n,
|
|
147
|
-
|
|
159
|
+
a,
|
|
148
160
|
s,
|
|
149
161
|
c,
|
|
150
162
|
r,
|
|
151
|
-
|
|
163
|
+
i
|
|
152
164
|
]
|
|
153
|
-
}), /* @__PURE__ */
|
|
165
|
+
}), /* @__PURE__ */ h("div", { ref: d });
|
|
154
166
|
}
|
|
155
|
-
function
|
|
156
|
-
let
|
|
157
|
-
iframeStyle:
|
|
167
|
+
function j({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48px", buttonProps: a, iframeProps: o, onConfirm: s }) {
|
|
168
|
+
let l = m(null), d = u({
|
|
169
|
+
iframeStyle: o?.style,
|
|
158
170
|
buttonProps: a
|
|
159
171
|
});
|
|
160
|
-
return
|
|
161
|
-
containerRef:
|
|
172
|
+
return E({
|
|
173
|
+
containerRef: l,
|
|
162
174
|
iframeRef: e,
|
|
163
|
-
mount:
|
|
175
|
+
mount: c,
|
|
164
176
|
options: {
|
|
165
177
|
renderToken: t,
|
|
166
178
|
amount: n,
|
|
167
179
|
merchantName: r,
|
|
168
180
|
height: i,
|
|
169
181
|
buttonProps: a,
|
|
170
|
-
|
|
171
|
-
onResult: u
|
|
182
|
+
onConfirm: s
|
|
172
183
|
},
|
|
173
184
|
remountDeps: [t],
|
|
174
|
-
iframePassthrough:
|
|
185
|
+
iframePassthrough: o ?? {},
|
|
175
186
|
updateDeps: [
|
|
176
187
|
n,
|
|
177
188
|
r,
|
|
178
189
|
i,
|
|
179
190
|
a,
|
|
180
|
-
|
|
181
|
-
u
|
|
191
|
+
s
|
|
182
192
|
]
|
|
183
|
-
}), /* @__PURE__ */
|
|
193
|
+
}), /* @__PURE__ */ h(O, {
|
|
184
194
|
height: i,
|
|
185
|
-
borderRadius:
|
|
186
|
-
containerRef:
|
|
195
|
+
borderRadius: d,
|
|
196
|
+
containerRef: l
|
|
187
197
|
});
|
|
188
198
|
}
|
|
189
|
-
function
|
|
190
|
-
let
|
|
199
|
+
function M({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48px", buttonProps: o, iframeProps: s, onConfirm: c }) {
|
|
200
|
+
let l = m(null), d = u({
|
|
191
201
|
iframeStyle: s?.style,
|
|
192
202
|
buttonProps: o
|
|
193
203
|
});
|
|
194
|
-
return
|
|
195
|
-
containerRef:
|
|
204
|
+
return E({
|
|
205
|
+
containerRef: l,
|
|
196
206
|
iframeRef: e,
|
|
197
|
-
mount:
|
|
207
|
+
mount: a,
|
|
198
208
|
options: {
|
|
199
209
|
renderToken: t,
|
|
200
210
|
amount: n,
|
|
201
|
-
merchantName:
|
|
202
|
-
height:
|
|
211
|
+
merchantName: r,
|
|
212
|
+
height: i,
|
|
203
213
|
buttonProps: o,
|
|
204
|
-
|
|
205
|
-
onResult: u
|
|
214
|
+
onConfirm: c
|
|
206
215
|
},
|
|
207
216
|
remountDeps: [t],
|
|
208
217
|
iframePassthrough: s ?? {},
|
|
209
218
|
updateDeps: [
|
|
210
219
|
n,
|
|
220
|
+
r,
|
|
211
221
|
i,
|
|
212
|
-
a,
|
|
213
222
|
o,
|
|
214
|
-
|
|
215
|
-
u
|
|
223
|
+
c
|
|
216
224
|
]
|
|
217
|
-
}), /* @__PURE__ */
|
|
218
|
-
height:
|
|
219
|
-
borderRadius:
|
|
220
|
-
containerRef:
|
|
225
|
+
}), /* @__PURE__ */ h(O, {
|
|
226
|
+
height: i,
|
|
227
|
+
borderRadius: d,
|
|
228
|
+
containerRef: l
|
|
221
229
|
});
|
|
222
230
|
}
|
|
223
231
|
//#endregion
|
|
224
|
-
export {
|
|
232
|
+
export { M as AmosApplePayButton, A as AmosBankAccountPaymentMethodForm, k as AmosCreditCardPaymentMethodForm, j as AmosGooglePayButton, y as confirmPayment, x as confirmPaymentIntent, b as confirmSetup, S as confirmSetupIntent, C as resetForm, v as validateForm };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amos.com/react-amos-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,22 +37,22 @@
|
|
|
37
37
|
"license": "MIT",
|
|
38
38
|
"description": "React SDK for embedding Amos payment methods via iframes. Wraps @amos.com/amos-js.",
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@amos.com/node": "0.1.
|
|
41
|
-
"@biomejs/biome": "2.5.
|
|
40
|
+
"@amos.com/node": "0.1.53",
|
|
41
|
+
"@biomejs/biome": "2.5.10",
|
|
42
42
|
"@changesets/cli": "2.31.1",
|
|
43
|
-
"@types/node": "26.
|
|
43
|
+
"@types/node": "26.3.0",
|
|
44
44
|
"@types/react": "19.2.18",
|
|
45
45
|
"@typescript/typescript6": "6.0.2",
|
|
46
46
|
"typescript": "7.0.2",
|
|
47
|
-
"vite": "8.2.
|
|
47
|
+
"vite": "8.2.2",
|
|
48
48
|
"vite-plugin-dts": "5.0.3"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@amos.com/amos-js": "0.
|
|
52
|
-
"@types/googlepay": "0.7.
|
|
51
|
+
"@amos.com/amos-js": "0.11.2",
|
|
52
|
+
"@types/googlepay": "0.7.12"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"react": "^17 || ^18 || ^19",
|
|
56
|
-
"@amos.com/node": ">=0.1.
|
|
56
|
+
"@amos.com/node": ">=0.1.53"
|
|
57
57
|
}
|
|
58
58
|
}
|
package/src/index.tsx
CHANGED
|
@@ -3,12 +3,15 @@
|
|
|
3
3
|
import {
|
|
4
4
|
type Appearance,
|
|
5
5
|
type ApplePayButtonElementProps,
|
|
6
|
+
confirmPayment as amosConfirmPayment,
|
|
6
7
|
confirmPaymentIntent as amosConfirmPaymentIntent,
|
|
8
|
+
confirmSetup as amosConfirmSetup,
|
|
7
9
|
confirmSetupIntent as amosConfirmSetupIntent,
|
|
8
10
|
resetForm as amosResetForm,
|
|
9
11
|
validateForm as amosValidateForm,
|
|
10
12
|
type BillingAddressRequirement,
|
|
11
13
|
type ConfirmationResult,
|
|
14
|
+
type ConfirmResult,
|
|
12
15
|
type CreditCardAdditionalFields,
|
|
13
16
|
ensureSkeletonStyles,
|
|
14
17
|
type GooglePayButtonElementProps,
|
|
@@ -60,13 +63,16 @@ export function validateForm({
|
|
|
60
63
|
* Pass the embed JWT (`token`) returned by your server's
|
|
61
64
|
* `POST /payment_intents` call.
|
|
62
65
|
*/
|
|
63
|
-
export function
|
|
66
|
+
export function confirmPayment({
|
|
64
67
|
iframeRef,
|
|
65
68
|
token,
|
|
66
69
|
}: {
|
|
67
70
|
iframeRef: IframeRef;
|
|
68
|
-
} & Pick<
|
|
69
|
-
|
|
71
|
+
} & Pick<
|
|
72
|
+
components["schemas"]["EmbedToken"],
|
|
73
|
+
"token"
|
|
74
|
+
>): Promise<ConfirmResult> {
|
|
75
|
+
return amosConfirmPayment({ iframe: resolveIframe(iframeRef), token });
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
/**
|
|
@@ -76,13 +82,46 @@ export function confirmPaymentIntent({
|
|
|
76
82
|
* Pass the embed JWT (`token`) returned by your server's
|
|
77
83
|
* `POST /setup_intents` call.
|
|
78
84
|
*/
|
|
85
|
+
export function confirmSetup({
|
|
86
|
+
iframeRef,
|
|
87
|
+
token,
|
|
88
|
+
}: {
|
|
89
|
+
iframeRef: IframeRef;
|
|
90
|
+
} & Pick<
|
|
91
|
+
components["schemas"]["EmbedToken"],
|
|
92
|
+
"token"
|
|
93
|
+
>): Promise<ConfirmResult> {
|
|
94
|
+
return amosConfirmSetup({ iframe: resolveIframe(iframeRef), token });
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @deprecated Use {@link confirmPayment}.
|
|
99
|
+
*/
|
|
100
|
+
export function confirmPaymentIntent({
|
|
101
|
+
iframeRef,
|
|
102
|
+
token,
|
|
103
|
+
}: {
|
|
104
|
+
iframeRef: IframeRef;
|
|
105
|
+
} & Pick<
|
|
106
|
+
components["schemas"]["EmbedToken"],
|
|
107
|
+
"token"
|
|
108
|
+
>): Promise<ConfirmResult> {
|
|
109
|
+
return amosConfirmPaymentIntent({ iframe: resolveIframe(iframeRef), token });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated Use {@link confirmSetup}.
|
|
114
|
+
*/
|
|
79
115
|
export function confirmSetupIntent({
|
|
80
116
|
iframeRef,
|
|
81
117
|
token,
|
|
82
118
|
}: {
|
|
83
119
|
iframeRef: IframeRef;
|
|
84
|
-
} & Pick<
|
|
85
|
-
|
|
120
|
+
} & Pick<
|
|
121
|
+
components["schemas"]["EmbedToken"],
|
|
122
|
+
"token"
|
|
123
|
+
>): Promise<ConfirmResult> {
|
|
124
|
+
return amosConfirmSetupIntent({ iframe: resolveIframe(iframeRef), token });
|
|
86
125
|
}
|
|
87
126
|
|
|
88
127
|
/**
|
|
@@ -247,7 +286,10 @@ function WalletButtonSlot({
|
|
|
247
286
|
type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
248
287
|
renderToken: string;
|
|
249
288
|
appearance?: Appearance;
|
|
250
|
-
|
|
289
|
+
/**
|
|
290
|
+
* @deprecated Prefer `await confirmPayment()` / `await confirmSetup()`.
|
|
291
|
+
*/
|
|
292
|
+
onResult?: (result: ConfirmationResult) => void;
|
|
251
293
|
/**
|
|
252
294
|
* Called when form validity changes. `isValid` is true when all
|
|
253
295
|
* required fields are present and valid. Does not include PCI data.
|
|
@@ -321,7 +363,10 @@ export function AmosCreditCardPaymentMethodForm({
|
|
|
321
363
|
type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
322
364
|
renderToken: string;
|
|
323
365
|
appearance?: Appearance;
|
|
324
|
-
|
|
366
|
+
/**
|
|
367
|
+
* @deprecated Prefer `await confirmPayment()` / `await confirmSetup()`.
|
|
368
|
+
*/
|
|
369
|
+
onResult?: (result: ConfirmationResult) => void;
|
|
325
370
|
/**
|
|
326
371
|
* Called when form validity changes. `isValid` is true when all
|
|
327
372
|
* required fields are present and valid, or when Plaid Link has
|
|
@@ -419,14 +464,19 @@ type AmosGooglePayButtonProps = {
|
|
|
419
464
|
buttonProps?: GooglePayButtonElementProps;
|
|
420
465
|
/** Props applied to the host-page `<iframe>` element. */
|
|
421
466
|
iframeProps?: IframePassthroughProps;
|
|
422
|
-
|
|
467
|
+
/**
|
|
468
|
+
* Called when the buyer authorizes in the Google Pay sheet. Create a
|
|
469
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
470
|
+
*/
|
|
471
|
+
onConfirm: ({
|
|
423
472
|
paymentIntentCreateAttributes,
|
|
424
473
|
customerCreateAttributes,
|
|
474
|
+
confirmPayment,
|
|
425
475
|
}: {
|
|
426
476
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
427
477
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
428
|
-
|
|
429
|
-
|
|
478
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
479
|
+
}) => Promise<ConfirmResult>;
|
|
430
480
|
};
|
|
431
481
|
|
|
432
482
|
/**
|
|
@@ -442,8 +492,7 @@ export function AmosGooglePayButton({
|
|
|
442
492
|
height = "48px",
|
|
443
493
|
buttonProps,
|
|
444
494
|
iframeProps,
|
|
445
|
-
|
|
446
|
-
onResult,
|
|
495
|
+
onConfirm,
|
|
447
496
|
}: AmosGooglePayButtonProps) {
|
|
448
497
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
449
498
|
const borderRadius = resolveWalletButtonSkeletonBorderRadius({
|
|
@@ -461,19 +510,11 @@ export function AmosGooglePayButton({
|
|
|
461
510
|
merchantName,
|
|
462
511
|
height,
|
|
463
512
|
buttonProps,
|
|
464
|
-
|
|
465
|
-
onResult,
|
|
513
|
+
onConfirm,
|
|
466
514
|
},
|
|
467
515
|
remountDeps: [renderToken],
|
|
468
516
|
iframePassthrough: iframeProps ?? {},
|
|
469
|
-
updateDeps: [
|
|
470
|
-
amount,
|
|
471
|
-
merchantName,
|
|
472
|
-
height,
|
|
473
|
-
buttonProps,
|
|
474
|
-
onInitiatePaymentIntentRequest,
|
|
475
|
-
onResult,
|
|
476
|
-
],
|
|
517
|
+
updateDeps: [amount, merchantName, height, buttonProps, onConfirm],
|
|
477
518
|
});
|
|
478
519
|
|
|
479
520
|
return (
|
|
@@ -509,14 +550,19 @@ type AmosApplePayButtonProps = {
|
|
|
509
550
|
buttonProps?: ApplePayButtonElementProps;
|
|
510
551
|
/** Props applied to the host-page `<iframe>` element. */
|
|
511
552
|
iframeProps?: IframePassthroughProps;
|
|
512
|
-
|
|
553
|
+
/**
|
|
554
|
+
* Called when the buyer authorizes in the Apple Pay sheet. Create a
|
|
555
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
556
|
+
*/
|
|
557
|
+
onConfirm: ({
|
|
513
558
|
paymentIntentCreateAttributes,
|
|
514
559
|
customerCreateAttributes,
|
|
560
|
+
confirmPayment,
|
|
515
561
|
}: {
|
|
516
562
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
517
563
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
518
|
-
|
|
519
|
-
|
|
564
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
565
|
+
}) => Promise<ConfirmResult>;
|
|
520
566
|
};
|
|
521
567
|
|
|
522
568
|
/**
|
|
@@ -532,8 +578,7 @@ export function AmosApplePayButton({
|
|
|
532
578
|
height = "48px",
|
|
533
579
|
buttonProps,
|
|
534
580
|
iframeProps,
|
|
535
|
-
|
|
536
|
-
onResult,
|
|
581
|
+
onConfirm,
|
|
537
582
|
}: AmosApplePayButtonProps) {
|
|
538
583
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
539
584
|
const borderRadius = resolveWalletButtonSkeletonBorderRadius({
|
|
@@ -551,19 +596,11 @@ export function AmosApplePayButton({
|
|
|
551
596
|
merchantName,
|
|
552
597
|
height,
|
|
553
598
|
buttonProps,
|
|
554
|
-
|
|
555
|
-
onResult,
|
|
599
|
+
onConfirm,
|
|
556
600
|
},
|
|
557
601
|
remountDeps: [renderToken],
|
|
558
602
|
iframePassthrough: iframeProps ?? {},
|
|
559
|
-
updateDeps: [
|
|
560
|
-
amount,
|
|
561
|
-
merchantName,
|
|
562
|
-
height,
|
|
563
|
-
buttonProps,
|
|
564
|
-
onInitiatePaymentIntentRequest,
|
|
565
|
-
onResult,
|
|
566
|
-
],
|
|
603
|
+
updateDeps: [amount, merchantName, height, buttonProps, onConfirm],
|
|
567
604
|
});
|
|
568
605
|
|
|
569
606
|
return (
|