@amos.com/react-amos-js 0.10.6 → 0.11.2
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 +63 -74
- package/dist/index.d.ts +24 -18
- package/dist/index.js +1 -1
- package/dist/index.mjs +46 -54
- package/package.json +8 -8
- package/src/index.tsx +38 -48
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`, `
|
|
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`, `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 })`.
|
|
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" }`.
|
|
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 })`.
|
|
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,18 +431,18 @@ 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" }`.
|
|
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
447
|
Confirms a setup intent in the embedded iframe flow. Use this when saving a payment method for future use.
|
|
454
448
|
|
|
@@ -457,11 +451,11 @@ Confirms a setup intent in the embedded iframe flow. Use this when saving a paym
|
|
|
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 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
|
|
|
@@ -495,7 +488,7 @@ Renders the secure bank account iframe form. A field-shaped skeleton is shown im
|
|
|
495
488
|
|
|
496
489
|
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
490
|
|
|
498
|
-
**Required props:** same as `AmosCreditCardPaymentMethodForm` — `renderToken
|
|
491
|
+
**Required props:** same as `AmosCreditCardPaymentMethodForm` — `renderToken` — plus:
|
|
499
492
|
|
|
500
493
|
- `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
494
|
- `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 +501,6 @@ Compare locally once the iframe posts `ACH_THRESHOLD`: Plaid when `requireVerifi
|
|
|
508
501
|
<AmosBankAccountPaymentMethodForm
|
|
509
502
|
renderToken={renderToken}
|
|
510
503
|
amount="50.00" // defaults to "0" (manual form until the charge meets the threshold)
|
|
511
|
-
onResult={onResult}
|
|
512
504
|
/>
|
|
513
505
|
```
|
|
514
506
|
|
|
@@ -518,11 +510,10 @@ Setup (always Connect, no merchant lookup):
|
|
|
518
510
|
<AmosBankAccountPaymentMethodForm
|
|
519
511
|
renderToken={renderToken}
|
|
520
512
|
intent="setup"
|
|
521
|
-
onResult={onResult}
|
|
522
513
|
/>
|
|
523
514
|
```
|
|
524
515
|
|
|
525
|
-
`validateForm` / `
|
|
516
|
+
`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
517
|
|
|
527
518
|
**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
519
|
|
|
@@ -537,9 +528,7 @@ Renders the secure Google Pay iframe button (express checkout flow). A button-sh
|
|
|
537
528
|
- `renderToken` (`string`)
|
|
538
529
|
- `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
530
|
- `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.
|
|
531
|
+
- `onConfirm` (callback receiving `{ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment }`. Create a payment intent, then `return confirmPayment(token)` — `Promise<ConfirmResult>`)
|
|
543
532
|
|
|
544
533
|
**Optional props:**
|
|
545
534
|
|
|
@@ -595,14 +584,14 @@ Re-exports of the same advanced helpers exposed by `@amos.com/amos-js`. Most int
|
|
|
595
584
|
|
|
596
585
|
### Exported types
|
|
597
586
|
|
|
598
|
-
`@amos.com/react-amos-js` re-exports everything from `@amos.com/amos-js`, including `
|
|
587
|
+
`@amos.com/react-amos-js` re-exports everything from `@amos.com/amos-js`, including `ConfirmResult`, `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
588
|
|
|
600
589
|
## Notes and potential gotchas
|
|
601
590
|
|
|
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 `
|
|
591
|
+
- **`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.
|
|
592
|
+
- **`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" }`.
|
|
593
|
+
- **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`).
|
|
594
|
+
- **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
595
|
- **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
596
|
- **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
597
|
- **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,
|
|
2
|
+
import { Appearance, ApplePayButtonElementProps, BillingAddressRequirement, 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,12 +30,12 @@ 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
|
|
33
|
+
export declare function confirmSetup({ iframeRef, token, }: {
|
|
34
34
|
iframeRef: IframeRef;
|
|
35
|
-
} & Pick<components["schemas"]["EmbedToken"], "token">):
|
|
35
|
+
} & Pick<components["schemas"]["EmbedToken"], "token">): Promise<ConfirmResult>;
|
|
36
36
|
/**
|
|
37
37
|
* Clear all field values and API errors in the embedded card/bank iframe
|
|
38
|
-
* form. Call after
|
|
38
|
+
* form. Call after a failed confirm when the customer wants to try again.
|
|
39
39
|
*/
|
|
40
40
|
export declare function resetForm({ iframeRef }: {
|
|
41
41
|
iframeRef: IframeRef;
|
|
@@ -45,7 +45,6 @@ type IframePassthroughProps = Omit<ComponentProps<"iframe">, "src" | "title" | "
|
|
|
45
45
|
type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
46
46
|
renderToken: string;
|
|
47
47
|
appearance?: Appearance;
|
|
48
|
-
onResult: (result: ConfirmationResult) => void;
|
|
49
48
|
/**
|
|
50
49
|
* Called when form validity changes. `isValid` is true when all
|
|
51
50
|
* required fields are present and valid. Does not include PCI data.
|
|
@@ -64,11 +63,10 @@ type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
|
64
63
|
additionalFields?: CreditCardAdditionalFields;
|
|
65
64
|
billingAddressRequirement?: BillingAddressRequirement;
|
|
66
65
|
};
|
|
67
|
-
export declare function AmosCreditCardPaymentMethodForm({ ref, renderToken, appearance,
|
|
66
|
+
export declare function AmosCreditCardPaymentMethodForm({ ref, renderToken, appearance, onValidityChange, onCardBrandChanged, additionalFields, billingAddressRequirement, style, ...rest }: AmosCreditCardPaymentMethodFormProps): import("react").JSX.Element;
|
|
68
67
|
type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
69
68
|
renderToken: string;
|
|
70
69
|
appearance?: Appearance;
|
|
71
|
-
onResult: (result: ConfirmationResult) => void;
|
|
72
70
|
/**
|
|
73
71
|
* Called when form validity changes. `isValid` is true when all
|
|
74
72
|
* required fields are present and valid, or when Plaid Link has
|
|
@@ -101,7 +99,7 @@ type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
|
101
99
|
*/
|
|
102
100
|
intent?: "payment" | "setup";
|
|
103
101
|
};
|
|
104
|
-
export declare function AmosBankAccountPaymentMethodForm({ ref, renderToken, appearance,
|
|
102
|
+
export declare function AmosBankAccountPaymentMethodForm({ ref, renderToken, appearance, onValidityChange, billingAddressRequirement, amount, intent, style, ...rest }: AmosBankAccountPaymentMethodFormProps): import("react").JSX.Element;
|
|
105
103
|
type AmosGooglePayButtonProps = {
|
|
106
104
|
ref?: ForwardedIframeRef;
|
|
107
105
|
renderToken: string;
|
|
@@ -126,18 +124,22 @@ type AmosGooglePayButtonProps = {
|
|
|
126
124
|
buttonProps?: GooglePayButtonElementProps;
|
|
127
125
|
/** Props applied to the host-page `<iframe>` element. */
|
|
128
126
|
iframeProps?: IframePassthroughProps;
|
|
129
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Called when the buyer authorizes in the Google Pay sheet. Create a
|
|
129
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
130
|
+
*/
|
|
131
|
+
onConfirm: ({ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment, }: {
|
|
130
132
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
131
133
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
132
|
-
|
|
133
|
-
|
|
134
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
135
|
+
}) => Promise<ConfirmResult>;
|
|
134
136
|
};
|
|
135
137
|
/**
|
|
136
138
|
* Renders the secure Google Pay iframe button. A button-shaped
|
|
137
139
|
* skeleton is painted in the parent document on first render (including
|
|
138
140
|
* SSR) so the slot height is reserved before the iframe loads.
|
|
139
141
|
*/
|
|
140
|
-
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps,
|
|
142
|
+
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps, onConfirm, }: AmosGooglePayButtonProps): import("react").JSX.Element;
|
|
141
143
|
type AmosApplePayButtonProps = {
|
|
142
144
|
ref?: ForwardedIframeRef;
|
|
143
145
|
renderToken: string;
|
|
@@ -162,15 +164,19 @@ type AmosApplePayButtonProps = {
|
|
|
162
164
|
buttonProps?: ApplePayButtonElementProps;
|
|
163
165
|
/** Props applied to the host-page `<iframe>` element. */
|
|
164
166
|
iframeProps?: IframePassthroughProps;
|
|
165
|
-
|
|
167
|
+
/**
|
|
168
|
+
* Called when the buyer authorizes in the Apple Pay sheet. Create a
|
|
169
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
170
|
+
*/
|
|
171
|
+
onConfirm: ({ paymentIntentCreateAttributes, customerCreateAttributes, confirmPayment, }: {
|
|
166
172
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
167
173
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
175
|
+
}) => Promise<ConfirmResult>;
|
|
170
176
|
};
|
|
171
177
|
/**
|
|
172
178
|
* Renders the secure Apple Pay iframe button. A button-shaped
|
|
173
179
|
* skeleton is painted in the parent document on first render (including
|
|
174
180
|
* SSR) so the slot height is reserved before the iframe loads.
|
|
175
181
|
*/
|
|
176
|
-
export declare function AmosApplePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps,
|
|
182
|
+
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}){(0,e.resetForm)({iframe:r(t)})}function c(e,t){typeof e==`function`?e(t):e&&(e.current=t)}function l(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 u({containerRef:e,iframeRef:n,mount:r,options:i,remountDeps:a,iframePassthrough:o,updateDeps:s}){let u=(0,t.useRef)(null);(0,t.useLayoutEffect)(()=>{let t=e.current;if(!t)return;let a=r(t,i);return u.current=a,c(n,a.iframe),l(a.iframe,o),()=>{a.destroy(),u.current=null,c(n,null)}},[...a]),(0,t.useEffect)(()=>{u.current?.update(i)},[...s]),(0,t.useEffect)(()=>{let e=u.current?.iframe;e&&l(e,o)})}var d=`oklch(0.97 0 0)`;function f({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:d,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 p({ref:r,renderToken:i,appearance:a,onValidityChange:o,onCardBrandChanged:s,additionalFields:c={cardholderName:!1},billingAddressRequirement:l=`country`,style:d,...f}){let p=(0,t.useRef)(null);return u({containerRef:p,iframeRef:r,mount:e.mountAmosCreditCardPaymentMethodForm,options:{renderToken:i,appearance:a,additionalFields:c,billingAddressRequirement:l,onValidityChange:o,onCardBrandChanged:s},remountDeps:[i,c.cardholderName,l],iframePassthrough:{style:d,...f},updateDeps:[a,c,l,o,s]}),(0,n.jsx)(`div`,{ref:p})}function m({ref:r,renderToken:i,appearance:a,onValidityChange:o,billingAddressRequirement:s=`country`,amount:c=`0`,intent:l=`payment`,style:d,...f}){let p=(0,t.useRef)(null);return u({containerRef:p,iframeRef:r,mount:e.mountAmosBankAccountPaymentMethodForm,options:{renderToken:i,appearance:a,billingAddressRequirement:s,amount:c,intent:l,onValidityChange:o},remountDeps:[i,s,l],iframePassthrough:{style:d,...f},updateDeps:[a,s,c,l,o]}),(0,n.jsx)(`div`,{ref:p})}function h({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onConfirm:d}){let p=(0,t.useRef)(null),m=(0,e.resolveWalletButtonSkeletonBorderRadius)({iframeStyle:l?.style,buttonProps:c});return u({containerRef:p,iframeRef:r,mount:e.mountAmosGooglePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onConfirm:d},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,d]}),(0,n.jsx)(f,{height:s,borderRadius:m,containerRef:p})}function g({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onConfirm:d}){let p=(0,t.useRef)(null),m=(0,e.resolveWalletButtonSkeletonBorderRadius)({iframeStyle:l?.style,buttonProps:c});return u({containerRef:p,iframeRef:r,mount:e.mountAmosApplePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onConfirm:d},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,d]}),(0,n.jsx)(f,{height:s,borderRadius:m,containerRef:p})}exports.AmosApplePayButton=g,exports.AmosBankAccountPaymentMethodForm=m,exports.AmosCreditCardPaymentMethodForm=p,exports.AmosGooglePayButton=h,exports.confirmPayment=a,exports.confirmSetup=o,exports.resetForm=s,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,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { confirmPayment as e, confirmSetup as t, ensureSkeletonStyles as n, mountAmosApplePayButton as r, mountAmosBankAccountPaymentMethodForm as i, mountAmosCreditCardPaymentMethodForm as a, mountAmosGooglePayButton as o, resetForm as s, resolveWalletButtonSkeletonBorderRadius as c, validateForm as l } from "@amos.com/amos-js";
|
|
2
2
|
import { useEffect as u, useLayoutEffect as d, useRef as f } from "react";
|
|
3
3
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
4
4
|
export * from "@amos.com/amos-js";
|
|
@@ -10,13 +10,13 @@ function g({ iframeRef: e }) {
|
|
|
10
10
|
return l({ iframe: h(e) });
|
|
11
11
|
}
|
|
12
12
|
function _({ iframeRef: t, token: n }) {
|
|
13
|
-
e({
|
|
13
|
+
return e({
|
|
14
14
|
iframe: h(t),
|
|
15
15
|
token: n
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
function v({ iframeRef: e, token: n }) {
|
|
19
|
-
t({
|
|
19
|
+
return t({
|
|
20
20
|
iframe: h(e),
|
|
21
21
|
token: n
|
|
22
22
|
});
|
|
@@ -84,81 +84,77 @@ function w({ height: e, borderRadius: t, containerRef: r }) {
|
|
|
84
84
|
})]
|
|
85
85
|
});
|
|
86
86
|
}
|
|
87
|
-
function T({ ref: e, renderToken: t, appearance: n,
|
|
88
|
-
let
|
|
87
|
+
function T({ ref: e, renderToken: t, appearance: n, onValidityChange: r, onCardBrandChanged: i, additionalFields: o = { cardholderName: !1 }, billingAddressRequirement: s = "country", style: c, ...l }) {
|
|
88
|
+
let u = f(null);
|
|
89
89
|
return S({
|
|
90
|
-
containerRef:
|
|
90
|
+
containerRef: u,
|
|
91
91
|
iframeRef: e,
|
|
92
92
|
mount: a,
|
|
93
93
|
options: {
|
|
94
94
|
renderToken: t,
|
|
95
95
|
appearance: n,
|
|
96
|
-
additionalFields:
|
|
97
|
-
billingAddressRequirement:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
onCardBrandChanged: o
|
|
96
|
+
additionalFields: o,
|
|
97
|
+
billingAddressRequirement: s,
|
|
98
|
+
onValidityChange: r,
|
|
99
|
+
onCardBrandChanged: i
|
|
101
100
|
},
|
|
102
101
|
remountDeps: [
|
|
103
102
|
t,
|
|
104
|
-
|
|
105
|
-
|
|
103
|
+
o.cardholderName,
|
|
104
|
+
s
|
|
106
105
|
],
|
|
107
106
|
iframePassthrough: {
|
|
108
|
-
style:
|
|
109
|
-
...
|
|
107
|
+
style: c,
|
|
108
|
+
...l
|
|
110
109
|
},
|
|
111
110
|
updateDeps: [
|
|
112
111
|
n,
|
|
112
|
+
o,
|
|
113
113
|
s,
|
|
114
|
-
c,
|
|
115
114
|
r,
|
|
116
|
-
i
|
|
117
|
-
o
|
|
115
|
+
i
|
|
118
116
|
]
|
|
119
|
-
}), /* @__PURE__ */ p("div", { ref:
|
|
117
|
+
}), /* @__PURE__ */ p("div", { ref: u });
|
|
120
118
|
}
|
|
121
|
-
function E({ ref: e, renderToken: t, appearance: n,
|
|
122
|
-
let
|
|
119
|
+
function E({ ref: e, renderToken: t, appearance: n, onValidityChange: r, billingAddressRequirement: a = "country", amount: o = "0", intent: s = "payment", style: c, ...l }) {
|
|
120
|
+
let u = f(null);
|
|
123
121
|
return S({
|
|
124
|
-
containerRef:
|
|
122
|
+
containerRef: u,
|
|
125
123
|
iframeRef: e,
|
|
126
124
|
mount: i,
|
|
127
125
|
options: {
|
|
128
126
|
renderToken: t,
|
|
129
127
|
appearance: n,
|
|
130
|
-
billingAddressRequirement:
|
|
131
|
-
amount:
|
|
132
|
-
intent:
|
|
133
|
-
|
|
134
|
-
onValidityChange: a
|
|
128
|
+
billingAddressRequirement: a,
|
|
129
|
+
amount: o,
|
|
130
|
+
intent: s,
|
|
131
|
+
onValidityChange: r
|
|
135
132
|
},
|
|
136
133
|
remountDeps: [
|
|
137
134
|
t,
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
a,
|
|
136
|
+
s
|
|
140
137
|
],
|
|
141
138
|
iframePassthrough: {
|
|
142
|
-
style:
|
|
143
|
-
...
|
|
139
|
+
style: c,
|
|
140
|
+
...l
|
|
144
141
|
},
|
|
145
142
|
updateDeps: [
|
|
146
143
|
n,
|
|
144
|
+
a,
|
|
147
145
|
o,
|
|
148
146
|
s,
|
|
149
|
-
|
|
150
|
-
r,
|
|
151
|
-
a
|
|
147
|
+
r
|
|
152
148
|
]
|
|
153
|
-
}), /* @__PURE__ */ p("div", { ref:
|
|
149
|
+
}), /* @__PURE__ */ p("div", { ref: u });
|
|
154
150
|
}
|
|
155
|
-
function D({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48px", buttonProps: a, iframeProps: s,
|
|
156
|
-
let
|
|
151
|
+
function D({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48px", buttonProps: a, iframeProps: s, onConfirm: l }) {
|
|
152
|
+
let u = f(null), d = c({
|
|
157
153
|
iframeStyle: s?.style,
|
|
158
154
|
buttonProps: a
|
|
159
155
|
});
|
|
160
156
|
return S({
|
|
161
|
-
containerRef:
|
|
157
|
+
containerRef: u,
|
|
162
158
|
iframeRef: e,
|
|
163
159
|
mount: o,
|
|
164
160
|
options: {
|
|
@@ -167,8 +163,7 @@ function D({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48
|
|
|
167
163
|
merchantName: r,
|
|
168
164
|
height: i,
|
|
169
165
|
buttonProps: a,
|
|
170
|
-
|
|
171
|
-
onResult: u
|
|
166
|
+
onConfirm: l
|
|
172
167
|
},
|
|
173
168
|
remountDeps: [t],
|
|
174
169
|
iframePassthrough: s ?? {},
|
|
@@ -177,22 +172,21 @@ function D({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48
|
|
|
177
172
|
r,
|
|
178
173
|
i,
|
|
179
174
|
a,
|
|
180
|
-
l
|
|
181
|
-
u
|
|
175
|
+
l
|
|
182
176
|
]
|
|
183
177
|
}), /* @__PURE__ */ p(w, {
|
|
184
178
|
height: i,
|
|
185
|
-
borderRadius:
|
|
186
|
-
containerRef:
|
|
179
|
+
borderRadius: d,
|
|
180
|
+
containerRef: u
|
|
187
181
|
});
|
|
188
182
|
}
|
|
189
|
-
function O({ ref: e, renderToken: t, amount: n, merchantName: i, height: a = "48px", buttonProps: o, iframeProps: s,
|
|
190
|
-
let
|
|
183
|
+
function O({ ref: e, renderToken: t, amount: n, merchantName: i, height: a = "48px", buttonProps: o, iframeProps: s, onConfirm: l }) {
|
|
184
|
+
let u = f(null), d = c({
|
|
191
185
|
iframeStyle: s?.style,
|
|
192
186
|
buttonProps: o
|
|
193
187
|
});
|
|
194
188
|
return S({
|
|
195
|
-
containerRef:
|
|
189
|
+
containerRef: u,
|
|
196
190
|
iframeRef: e,
|
|
197
191
|
mount: r,
|
|
198
192
|
options: {
|
|
@@ -201,8 +195,7 @@ function O({ ref: e, renderToken: t, amount: n, merchantName: i, height: a = "48
|
|
|
201
195
|
merchantName: i,
|
|
202
196
|
height: a,
|
|
203
197
|
buttonProps: o,
|
|
204
|
-
|
|
205
|
-
onResult: u
|
|
198
|
+
onConfirm: l
|
|
206
199
|
},
|
|
207
200
|
remountDeps: [t],
|
|
208
201
|
iframePassthrough: s ?? {},
|
|
@@ -211,14 +204,13 @@ function O({ ref: e, renderToken: t, amount: n, merchantName: i, height: a = "48
|
|
|
211
204
|
i,
|
|
212
205
|
a,
|
|
213
206
|
o,
|
|
214
|
-
l
|
|
215
|
-
u
|
|
207
|
+
l
|
|
216
208
|
]
|
|
217
209
|
}), /* @__PURE__ */ p(w, {
|
|
218
210
|
height: a,
|
|
219
|
-
borderRadius:
|
|
220
|
-
containerRef:
|
|
211
|
+
borderRadius: d,
|
|
212
|
+
containerRef: u
|
|
221
213
|
});
|
|
222
214
|
}
|
|
223
215
|
//#endregion
|
|
224
|
-
export { O as AmosApplePayButton, E as AmosBankAccountPaymentMethodForm, T as AmosCreditCardPaymentMethodForm, D as AmosGooglePayButton, _ as
|
|
216
|
+
export { O as AmosApplePayButton, E as AmosBankAccountPaymentMethodForm, T as AmosCreditCardPaymentMethodForm, D as AmosGooglePayButton, _ as confirmPayment, v as confirmSetup, y as resetForm, g 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.2",
|
|
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.3",
|
|
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,12 @@
|
|
|
3
3
|
import {
|
|
4
4
|
type Appearance,
|
|
5
5
|
type ApplePayButtonElementProps,
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
confirmPayment as amosConfirmPayment,
|
|
7
|
+
confirmSetup as amosConfirmSetup,
|
|
8
8
|
resetForm as amosResetForm,
|
|
9
9
|
validateForm as amosValidateForm,
|
|
10
10
|
type BillingAddressRequirement,
|
|
11
|
-
type
|
|
11
|
+
type ConfirmResult,
|
|
12
12
|
type CreditCardAdditionalFields,
|
|
13
13
|
ensureSkeletonStyles,
|
|
14
14
|
type GooglePayButtonElementProps,
|
|
@@ -60,13 +60,16 @@ export function validateForm({
|
|
|
60
60
|
* Pass the embed JWT (`token`) returned by your server's
|
|
61
61
|
* `POST /payment_intents` call.
|
|
62
62
|
*/
|
|
63
|
-
export function
|
|
63
|
+
export function confirmPayment({
|
|
64
64
|
iframeRef,
|
|
65
65
|
token,
|
|
66
66
|
}: {
|
|
67
67
|
iframeRef: IframeRef;
|
|
68
|
-
} & Pick<
|
|
69
|
-
|
|
68
|
+
} & Pick<
|
|
69
|
+
components["schemas"]["EmbedToken"],
|
|
70
|
+
"token"
|
|
71
|
+
>): Promise<ConfirmResult> {
|
|
72
|
+
return amosConfirmPayment({ iframe: resolveIframe(iframeRef), token });
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
/**
|
|
@@ -76,18 +79,21 @@ export function confirmPaymentIntent({
|
|
|
76
79
|
* Pass the embed JWT (`token`) returned by your server's
|
|
77
80
|
* `POST /setup_intents` call.
|
|
78
81
|
*/
|
|
79
|
-
export function
|
|
82
|
+
export function confirmSetup({
|
|
80
83
|
iframeRef,
|
|
81
84
|
token,
|
|
82
85
|
}: {
|
|
83
86
|
iframeRef: IframeRef;
|
|
84
|
-
} & Pick<
|
|
85
|
-
|
|
87
|
+
} & Pick<
|
|
88
|
+
components["schemas"]["EmbedToken"],
|
|
89
|
+
"token"
|
|
90
|
+
>): Promise<ConfirmResult> {
|
|
91
|
+
return amosConfirmSetup({ iframe: resolveIframe(iframeRef), token });
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
/**
|
|
89
95
|
* Clear all field values and API errors in the embedded card/bank iframe
|
|
90
|
-
* form. Call after
|
|
96
|
+
* form. Call after a failed confirm when the customer wants to try again.
|
|
91
97
|
*/
|
|
92
98
|
export function resetForm({ iframeRef }: { iframeRef: IframeRef }): void {
|
|
93
99
|
amosResetForm({ iframe: resolveIframe(iframeRef) });
|
|
@@ -247,7 +253,6 @@ function WalletButtonSlot({
|
|
|
247
253
|
type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
248
254
|
renderToken: string;
|
|
249
255
|
appearance?: Appearance;
|
|
250
|
-
onResult: (result: ConfirmationResult) => void;
|
|
251
256
|
/**
|
|
252
257
|
* Called when form validity changes. `isValid` is true when all
|
|
253
258
|
* required fields are present and valid. Does not include PCI data.
|
|
@@ -276,7 +281,6 @@ export function AmosCreditCardPaymentMethodForm({
|
|
|
276
281
|
ref,
|
|
277
282
|
renderToken,
|
|
278
283
|
appearance,
|
|
279
|
-
onResult,
|
|
280
284
|
onValidityChange,
|
|
281
285
|
onCardBrandChanged,
|
|
282
286
|
additionalFields = { cardholderName: false },
|
|
@@ -295,7 +299,6 @@ export function AmosCreditCardPaymentMethodForm({
|
|
|
295
299
|
appearance,
|
|
296
300
|
additionalFields,
|
|
297
301
|
billingAddressRequirement,
|
|
298
|
-
onResult,
|
|
299
302
|
onValidityChange,
|
|
300
303
|
onCardBrandChanged,
|
|
301
304
|
},
|
|
@@ -309,7 +312,6 @@ export function AmosCreditCardPaymentMethodForm({
|
|
|
309
312
|
appearance,
|
|
310
313
|
additionalFields,
|
|
311
314
|
billingAddressRequirement,
|
|
312
|
-
onResult,
|
|
313
315
|
onValidityChange,
|
|
314
316
|
onCardBrandChanged,
|
|
315
317
|
],
|
|
@@ -321,7 +323,6 @@ export function AmosCreditCardPaymentMethodForm({
|
|
|
321
323
|
type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
322
324
|
renderToken: string;
|
|
323
325
|
appearance?: Appearance;
|
|
324
|
-
onResult: (result: ConfirmationResult) => void;
|
|
325
326
|
/**
|
|
326
327
|
* Called when form validity changes. `isValid` is true when all
|
|
327
328
|
* required fields are present and valid, or when Plaid Link has
|
|
@@ -357,7 +358,6 @@ export function AmosBankAccountPaymentMethodForm({
|
|
|
357
358
|
ref,
|
|
358
359
|
renderToken,
|
|
359
360
|
appearance,
|
|
360
|
-
onResult,
|
|
361
361
|
onValidityChange,
|
|
362
362
|
billingAddressRequirement = "country",
|
|
363
363
|
amount = "0",
|
|
@@ -377,7 +377,6 @@ export function AmosBankAccountPaymentMethodForm({
|
|
|
377
377
|
billingAddressRequirement,
|
|
378
378
|
amount,
|
|
379
379
|
intent,
|
|
380
|
-
onResult,
|
|
381
380
|
onValidityChange,
|
|
382
381
|
},
|
|
383
382
|
remountDeps: [renderToken, billingAddressRequirement, intent],
|
|
@@ -387,7 +386,6 @@ export function AmosBankAccountPaymentMethodForm({
|
|
|
387
386
|
billingAddressRequirement,
|
|
388
387
|
amount,
|
|
389
388
|
intent,
|
|
390
|
-
onResult,
|
|
391
389
|
onValidityChange,
|
|
392
390
|
],
|
|
393
391
|
});
|
|
@@ -419,14 +417,19 @@ type AmosGooglePayButtonProps = {
|
|
|
419
417
|
buttonProps?: GooglePayButtonElementProps;
|
|
420
418
|
/** Props applied to the host-page `<iframe>` element. */
|
|
421
419
|
iframeProps?: IframePassthroughProps;
|
|
422
|
-
|
|
420
|
+
/**
|
|
421
|
+
* Called when the buyer authorizes in the Google Pay sheet. Create a
|
|
422
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
423
|
+
*/
|
|
424
|
+
onConfirm: ({
|
|
423
425
|
paymentIntentCreateAttributes,
|
|
424
426
|
customerCreateAttributes,
|
|
427
|
+
confirmPayment,
|
|
425
428
|
}: {
|
|
426
429
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
427
430
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
428
|
-
|
|
429
|
-
|
|
431
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
432
|
+
}) => Promise<ConfirmResult>;
|
|
430
433
|
};
|
|
431
434
|
|
|
432
435
|
/**
|
|
@@ -442,8 +445,7 @@ export function AmosGooglePayButton({
|
|
|
442
445
|
height = "48px",
|
|
443
446
|
buttonProps,
|
|
444
447
|
iframeProps,
|
|
445
|
-
|
|
446
|
-
onResult,
|
|
448
|
+
onConfirm,
|
|
447
449
|
}: AmosGooglePayButtonProps) {
|
|
448
450
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
449
451
|
const borderRadius = resolveWalletButtonSkeletonBorderRadius({
|
|
@@ -461,19 +463,11 @@ export function AmosGooglePayButton({
|
|
|
461
463
|
merchantName,
|
|
462
464
|
height,
|
|
463
465
|
buttonProps,
|
|
464
|
-
|
|
465
|
-
onResult,
|
|
466
|
+
onConfirm,
|
|
466
467
|
},
|
|
467
468
|
remountDeps: [renderToken],
|
|
468
469
|
iframePassthrough: iframeProps ?? {},
|
|
469
|
-
updateDeps: [
|
|
470
|
-
amount,
|
|
471
|
-
merchantName,
|
|
472
|
-
height,
|
|
473
|
-
buttonProps,
|
|
474
|
-
onInitiatePaymentIntentRequest,
|
|
475
|
-
onResult,
|
|
476
|
-
],
|
|
470
|
+
updateDeps: [amount, merchantName, height, buttonProps, onConfirm],
|
|
477
471
|
});
|
|
478
472
|
|
|
479
473
|
return (
|
|
@@ -509,14 +503,19 @@ type AmosApplePayButtonProps = {
|
|
|
509
503
|
buttonProps?: ApplePayButtonElementProps;
|
|
510
504
|
/** Props applied to the host-page `<iframe>` element. */
|
|
511
505
|
iframeProps?: IframePassthroughProps;
|
|
512
|
-
|
|
506
|
+
/**
|
|
507
|
+
* Called when the buyer authorizes in the Apple Pay sheet. Create a
|
|
508
|
+
* payment intent on your server, then `await confirmPayment(token)`.
|
|
509
|
+
*/
|
|
510
|
+
onConfirm: ({
|
|
513
511
|
paymentIntentCreateAttributes,
|
|
514
512
|
customerCreateAttributes,
|
|
513
|
+
confirmPayment,
|
|
515
514
|
}: {
|
|
516
515
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
517
516
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
518
|
-
|
|
519
|
-
|
|
517
|
+
confirmPayment: (token: string) => Promise<ConfirmResult>;
|
|
518
|
+
}) => Promise<ConfirmResult>;
|
|
520
519
|
};
|
|
521
520
|
|
|
522
521
|
/**
|
|
@@ -532,8 +531,7 @@ export function AmosApplePayButton({
|
|
|
532
531
|
height = "48px",
|
|
533
532
|
buttonProps,
|
|
534
533
|
iframeProps,
|
|
535
|
-
|
|
536
|
-
onResult,
|
|
534
|
+
onConfirm,
|
|
537
535
|
}: AmosApplePayButtonProps) {
|
|
538
536
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
539
537
|
const borderRadius = resolveWalletButtonSkeletonBorderRadius({
|
|
@@ -551,19 +549,11 @@ export function AmosApplePayButton({
|
|
|
551
549
|
merchantName,
|
|
552
550
|
height,
|
|
553
551
|
buttonProps,
|
|
554
|
-
|
|
555
|
-
onResult,
|
|
552
|
+
onConfirm,
|
|
556
553
|
},
|
|
557
554
|
remountDeps: [renderToken],
|
|
558
555
|
iframePassthrough: iframeProps ?? {},
|
|
559
|
-
updateDeps: [
|
|
560
|
-
amount,
|
|
561
|
-
merchantName,
|
|
562
|
-
height,
|
|
563
|
-
buttonProps,
|
|
564
|
-
onInitiatePaymentIntentRequest,
|
|
565
|
-
onResult,
|
|
566
|
-
],
|
|
556
|
+
updateDeps: [amount, merchantName, height, buttonProps, onConfirm],
|
|
567
557
|
});
|
|
568
558
|
|
|
569
559
|
return (
|