@amos.com/react-amos-js 0.9.13 → 0.9.15
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 +162 -125
- package/dist/index.d.ts +47 -26
- package/dist/index.js +1 -1
- package/dist/index.mjs +32 -79
- package/package.json +2 -2
- package/src/index.tsx +83 -149
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ It is a thin wrapper around [`@amos.com/amos-js`](../amos-js) that adapts the fr
|
|
|
10
10
|
npm install @amos.com/react-amos-js @amos.com/node
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
`@amos.com/node` is a **peer dependency** (requires `>=0.1.
|
|
13
|
+
`@amos.com/node` is a **peer dependency** (requires `>=0.1.39`). Install it in your app for OpenAPI schema types (for example `components["schemas"]["CreatePaymentIntentInput"]`) used in the examples below, and for your server-side Amos API client. React (`^17`, `^18`, or `^19`) is also a peer dependency.
|
|
14
14
|
|
|
15
15
|
## What it gives you
|
|
16
16
|
|
|
@@ -28,7 +28,7 @@ npm install @amos.com/react-amos-js @amos.com/node
|
|
|
28
28
|
3. Amos account ID (provided once your application has been approved)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
The render token configures the iframe's allowed origin(s), allowed payment methods, and the range of valid payment amounts. If the render token does not allow an origin, the iframe will not render. Similarly, components corresponding to different payment method types will not render if not allowed by the render token.
|
|
31
|
+
The render token configures the iframe's allowed origin(s), allowed payment methods, accepted billing countries or US states, and the range of valid payment amounts. These settings come from the render template and are embedded in the token JWT (`RenderTokenJwt`); billing geography is controlled by `billing_address_options` (`allowed_countries` for international templates, `allowed_states` for US-only). If the render token does not allow an origin, the iframe will not render. Similarly, components corresponding to different payment method types will not render if not allowed by the render token, and billing addresses outside the configured countries or states will be rejected.
|
|
32
32
|
|
|
33
33
|
> **Note**: The render token also determines the environment (`production` or `sandbox`). Render tokens created on `dashboard.amos.com` have a `production` environment. Render tokens created on `dashboard-sandbox.amos.com` have a `sandbox` environment. Similarly, API keys can only access the environment that they were created in.
|
|
34
34
|
|
|
@@ -62,7 +62,7 @@ Setup intents are used to save payment methods for future use (e.g. recurring pa
|
|
|
62
62
|
|
|
63
63
|
- On the server, call `POST /setup_intents` instead of `POST /payment_intents`.
|
|
64
64
|
- On the client, call `confirmSetupIntent({ iframeRef, token })` instead of `confirmPaymentIntent({ iframeRef, token })`.
|
|
65
|
-
- The same `onResult` callback is used
|
|
65
|
+
- The same `onResult` callback is used; succeeded setup intents arrive as `{ status: "succeeded", intent: "setup", setupIntent }`.
|
|
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.
|
|
68
68
|
|
|
@@ -82,7 +82,7 @@ In short, your app orchestrates the payment flow, while sensitive payment data s
|
|
|
82
82
|
|
|
83
83
|
## Appearance
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
Card and bank components accept an optional `appearance` prop that controls the look of the iframe UI. It contains a `themeVariables` object whose keys are CSS custom-property names and whose values are strings, and an optional `labels` setting for field label placement. You can update this prop after page load to update the iframe appearance. Wallet buttons do not take `appearance`.
|
|
86
86
|
|
|
87
87
|
```tsx
|
|
88
88
|
<AmosCreditCardPaymentMethodForm
|
|
@@ -107,57 +107,57 @@ Every component accepts an optional `appearance` prop that controls the look of
|
|
|
107
107
|
|
|
108
108
|
Set `labels` to control how field labels are rendered in card and bank account forms:
|
|
109
109
|
|
|
110
|
-
| Value
|
|
111
|
-
|
|
|
112
|
-
| `above` (default) | Label text above each input
|
|
113
|
-
| `floating`
|
|
114
|
-
| `placeholder`
|
|
110
|
+
| Value | Behavior |
|
|
111
|
+
| ----------------- | --------------------------------------------------------- |
|
|
112
|
+
| `above` (default) | Label text above each input |
|
|
113
|
+
| `floating` | Label inside the control; moves up when focused or filled |
|
|
114
|
+
| `placeholder` | No visible label; placeholder and `aria-label` only |
|
|
115
115
|
|
|
116
116
|
Radio groups (e.g. account type) always use an above-style group label regardless of this setting.
|
|
117
117
|
|
|
118
118
|
### Available theme variables
|
|
119
119
|
|
|
120
|
-
| Variable
|
|
121
|
-
|
|
|
122
|
-
| `--background`
|
|
123
|
-
| `--foreground`
|
|
124
|
-
| `--primary`
|
|
125
|
-
| `--primary-foreground`
|
|
126
|
-
| `--secondary`
|
|
127
|
-
| `--secondary-foreground`
|
|
128
|
-
| `--muted`
|
|
129
|
-
| `--muted-foreground`
|
|
130
|
-
| `--accent`
|
|
131
|
-
| `--accent-foreground`
|
|
132
|
-
| `--destructive`
|
|
133
|
-
| `--destructive-foreground`
|
|
134
|
-
| `--border`
|
|
135
|
-
| `--popover`
|
|
136
|
-
| `--popover-foreground`
|
|
137
|
-
| `--input`
|
|
138
|
-
| `--input-background`
|
|
139
|
-
| `--input-height`
|
|
140
|
-
| `--input-font-size`
|
|
141
|
-
| `--input-font-weight`
|
|
142
|
-
| `--input-padding`
|
|
143
|
-
| `--input-border-width`
|
|
144
|
-
| `--input-shadow`
|
|
145
|
-
| `--floating-input-height`
|
|
146
|
-
| `--floating-label-font-size`
|
|
147
|
-
| `--floating-label-empty-font-size`
|
|
148
|
-
| `--floating-label-font-weight`
|
|
149
|
-
| `--floating-label-color`
|
|
150
|
-
| `--floating-label-floated-color`
|
|
151
|
-
| `--floating-label-offset`
|
|
152
|
-
| `--label-font-size`
|
|
153
|
-
| `--label-font-weight`
|
|
154
|
-
| `--field-gap`
|
|
155
|
-
| `--control-gap`
|
|
156
|
-
| `--error-font-size`
|
|
157
|
-
| `--radio-size`
|
|
158
|
-
| `--ring`
|
|
159
|
-
| `--ring-width`
|
|
160
|
-
| `--radius`
|
|
120
|
+
| Variable | Purpose | Default |
|
|
121
|
+
| ---------------------------------- | -------------------------------------------------------- | ------------------------------- |
|
|
122
|
+
| `--background` | Page body and base surface color | `oklch(1 0 0)` |
|
|
123
|
+
| `--foreground` | Default text color | `oklch(0.145 0 0)` |
|
|
124
|
+
| `--primary` | Button fill and input text-selection highlight | `oklch(0.205 0 0)` |
|
|
125
|
+
| `--primary-foreground` | Text on primary-colored surfaces | `oklch(0.985 0 0)` |
|
|
126
|
+
| `--secondary` | Secondary button fill | `oklch(0.97 0 0)` |
|
|
127
|
+
| `--secondary-foreground` | Text on secondary-colored surfaces | `oklch(0.205 0 0)` |
|
|
128
|
+
| `--muted` | Muted surface color | `oklch(0.97 0 0)` |
|
|
129
|
+
| `--muted-foreground` | Placeholder text, helper labels, muted icons | `oklch(0.556 0 0)` |
|
|
130
|
+
| `--accent` | Hover/focus highlight for interactive items | `oklch(0.97 0 0)` |
|
|
131
|
+
| `--accent-foreground` | Text on accent-highlighted items | `oklch(0.205 0 0)` |
|
|
132
|
+
| `--destructive` | Error/invalid state borders, icons, and field error text | `oklch(0.577 0.245 27.325)` |
|
|
133
|
+
| `--destructive-foreground` | Text on destructive-colored surfaces | `oklch(0.45 0.24 27.325)` |
|
|
134
|
+
| `--border` | General border color | `oklch(0.922 0 0)` |
|
|
135
|
+
| `--popover` | Dropdown / popover panel background | `oklch(1 0 0)` |
|
|
136
|
+
| `--popover-foreground` | Dropdown / popover panel text color | `oklch(0.145 0 0)` |
|
|
137
|
+
| `--input` | Input field border color | `oklch(0.922 0 0)` |
|
|
138
|
+
| `--input-background` | Input field background fill | `var(--background)` |
|
|
139
|
+
| `--input-height` | Height of text inputs and form controls | `2.25rem` |
|
|
140
|
+
| `--input-font-size` | Font size of text inputs and dropdown fields | `0.875rem` |
|
|
141
|
+
| `--input-font-weight` | Font weight of typed input values | `400` |
|
|
142
|
+
| `--input-padding` | Horizontal padding inside inputs | `0.75rem` |
|
|
143
|
+
| `--input-border-width` | Input field border width | `1px` |
|
|
144
|
+
| `--input-shadow` | Input field box shadow | `0 1px 2px 0 rgb(0 0 0 / 0.05)` |
|
|
145
|
+
| `--floating-input-height` | Height of inputs when labels are floating | `3.25rem` |
|
|
146
|
+
| `--floating-label-font-size` | Font size of floating labels when focused or filled | `0.75rem` |
|
|
147
|
+
| `--floating-label-empty-font-size` | Font size of floating labels when empty (unfocused) | `var(--input-font-size)` |
|
|
148
|
+
| `--floating-label-font-weight` | Font weight of floating labels | `500` |
|
|
149
|
+
| `--floating-label-color` | Color of floating labels when empty (unfocused) | `var(--muted-foreground)` |
|
|
150
|
+
| `--floating-label-floated-color` | Color of floating labels when focused or filled | `var(--floating-label-color)` |
|
|
151
|
+
| `--floating-label-offset` | Top offset of the shrunk floating label | `0.625rem` |
|
|
152
|
+
| `--label-font-size` | Font size of above-style field labels | `0.875rem` |
|
|
153
|
+
| `--label-font-weight` | Font weight of above-style field labels | `500` |
|
|
154
|
+
| `--field-gap` | Vertical gap between stacked form fields | `1rem` |
|
|
155
|
+
| `--control-gap` | Horizontal gap between side-by-side controls | `0.5rem` |
|
|
156
|
+
| `--error-font-size` | Font size of field-level error messages | `0.875rem` |
|
|
157
|
+
| `--radio-size` | Size of radio buttons on the bank account form | `1rem` |
|
|
158
|
+
| `--ring` | Focus ring and outline color | `oklch(0.708 0 0)` |
|
|
159
|
+
| `--ring-width` | Focus ring width | `3px` |
|
|
160
|
+
| `--radius` | Base border-radius (derived into sm/md/lg/xl) | `0.625rem` |
|
|
161
161
|
|
|
162
162
|
## Examples
|
|
163
163
|
|
|
@@ -192,10 +192,11 @@ function CheckoutForm() {
|
|
|
192
192
|
return;
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
-
const paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"] =
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
195
|
+
const paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"] =
|
|
196
|
+
{
|
|
197
|
+
amount: 5000, // $50.00 in cents
|
|
198
|
+
capture_method: "automatic",
|
|
199
|
+
};
|
|
199
200
|
|
|
200
201
|
const response = await fetch("/api/payment-intents", {
|
|
201
202
|
method: "POST",
|
|
@@ -246,58 +247,109 @@ function CheckoutForm() {
|
|
|
246
247
|
}
|
|
247
248
|
```
|
|
248
249
|
|
|
249
|
-
### Rendering Google Pay within your checkout flow
|
|
250
|
+
### Rendering Google Pay and Apple Pay within your checkout flow
|
|
250
251
|
|
|
251
252
|
```tsx
|
|
252
253
|
import { useState } from "react";
|
|
253
|
-
import {
|
|
254
|
+
import {
|
|
255
|
+
AmosApplePayButton,
|
|
256
|
+
AmosGooglePayButton,
|
|
257
|
+
type ConfirmationResult,
|
|
258
|
+
} from "@amos.com/react-amos-js";
|
|
259
|
+
import type { components } from "@amos.com/node";
|
|
260
|
+
|
|
261
|
+
async function createPaymentIntentToken({
|
|
262
|
+
paymentIntentCreateAttributes,
|
|
263
|
+
customerCreateAttributes,
|
|
264
|
+
}: {
|
|
265
|
+
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
266
|
+
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
267
|
+
}): Promise<string> {
|
|
268
|
+
const response = await fetch("/api/payment-intents", {
|
|
269
|
+
method: "POST",
|
|
270
|
+
headers: { "Content-Type": "application/json" },
|
|
271
|
+
body: JSON.stringify({
|
|
272
|
+
customer: customerCreateAttributes,
|
|
273
|
+
paymentIntent: paymentIntentCreateAttributes,
|
|
274
|
+
}),
|
|
275
|
+
});
|
|
276
|
+
if (!response.ok) {
|
|
277
|
+
throw new Error("Failed to create payment intent.");
|
|
278
|
+
}
|
|
279
|
+
const { token } = (await response.json()) as { token: string };
|
|
280
|
+
return token;
|
|
281
|
+
}
|
|
254
282
|
|
|
255
|
-
function
|
|
283
|
+
function CheckoutWallets({ renderToken }: { renderToken: string }) {
|
|
256
284
|
const [error, setError] = useState<string | null>(null);
|
|
257
285
|
|
|
286
|
+
function handleResult(result: ConfirmationResult) {
|
|
287
|
+
if (result.status === "succeeded") {
|
|
288
|
+
console.log("Confirm returned:", result);
|
|
289
|
+
} else if (result.status === "failed") {
|
|
290
|
+
setError(result.errorMessage);
|
|
291
|
+
} else if (result.status === "incomplete") {
|
|
292
|
+
console.log("Recoverable:", result.reason);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
258
296
|
return (
|
|
259
297
|
<>
|
|
260
|
-
<
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const { token } = await response.json();
|
|
282
|
-
return token;
|
|
283
|
-
}}
|
|
284
|
-
onResult={(result) => {
|
|
285
|
-
if (result.status === "succeeded") {
|
|
286
|
-
console.log("Confirm returned:", result);
|
|
287
|
-
} else if (result.status === "failed") {
|
|
288
|
-
console.error("Confirm failed:", result.errorMessage);
|
|
289
|
-
} else if (result.status === "incomplete") {
|
|
290
|
-
console.log("Recoverable:", result.reason);
|
|
291
|
-
}
|
|
292
|
-
}}
|
|
293
|
-
/>
|
|
294
|
-
{error ? <p>{error}</p> : null}
|
|
298
|
+
<div style={{ display: "flex", gap: "12px" }}>
|
|
299
|
+
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
|
300
|
+
<AmosGooglePayButton
|
|
301
|
+
renderToken={renderToken}
|
|
302
|
+
amount="50.00"
|
|
303
|
+
merchantName="Example Store"
|
|
304
|
+
onInitiatePaymentIntentRequest={createPaymentIntentToken}
|
|
305
|
+
onResult={handleResult}
|
|
306
|
+
/>
|
|
307
|
+
</div>
|
|
308
|
+
<div style={{ flex: "1 1 0", minWidth: 0 }}>
|
|
309
|
+
<AmosApplePayButton
|
|
310
|
+
renderToken={renderToken}
|
|
311
|
+
amount="50.00"
|
|
312
|
+
merchantName="Example Store"
|
|
313
|
+
onInitiatePaymentIntentRequest={createPaymentIntentToken}
|
|
314
|
+
onResult={handleResult}
|
|
315
|
+
/>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
{error ? <p role="alert">{error}</p> : null}
|
|
295
319
|
</>
|
|
296
320
|
);
|
|
297
321
|
}
|
|
298
322
|
```
|
|
299
323
|
|
|
300
|
-
|
|
324
|
+
Do not call `validateForm` or `confirmPaymentIntent` — return the embed token from `onInitiatePaymentIntentRequest` and the SDK confirms. Size the mount slot; omitted `buttonProps` keep paint defaults and fill the iframe.
|
|
325
|
+
|
|
326
|
+
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
|
+
|
|
328
|
+
Optional visuals:
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
<AmosGooglePayButton
|
|
332
|
+
renderToken={renderToken}
|
|
333
|
+
amount="50.00"
|
|
334
|
+
merchantName="Example Store"
|
|
335
|
+
height="48px"
|
|
336
|
+
buttonProps={{ buttonType: "donate", buttonBorderType: "no_border" }}
|
|
337
|
+
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
338
|
+
onInitiatePaymentIntentRequest={createPaymentIntentToken}
|
|
339
|
+
onResult={handleResult}
|
|
340
|
+
/>
|
|
341
|
+
|
|
342
|
+
<AmosApplePayButton
|
|
343
|
+
renderToken={renderToken}
|
|
344
|
+
amount="50.00"
|
|
345
|
+
merchantName="Example Store"
|
|
346
|
+
height="48px"
|
|
347
|
+
buttonProps={{ type: "donate" }}
|
|
348
|
+
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
349
|
+
onInitiatePaymentIntentRequest={createPaymentIntentToken}
|
|
350
|
+
onResult={handleResult}
|
|
351
|
+
/>
|
|
352
|
+
```
|
|
301
353
|
|
|
302
354
|
### Saving a payment method with setup intent (credit card)
|
|
303
355
|
|
|
@@ -453,7 +505,7 @@ Renders the secure Google Pay iframe button (express checkout flow).
|
|
|
453
505
|
**Required props:**
|
|
454
506
|
|
|
455
507
|
- `renderToken` (`string`)
|
|
456
|
-
- `amount` (`string`)
|
|
508
|
+
- `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`.
|
|
457
509
|
- `merchantName` (`string`)
|
|
458
510
|
- `onInitiatePaymentIntentRequest` (callback receiving `{ paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"]; customerCreateAttributes: components["schemas"]["CreateCustomerInput"] }`, returns `Promise<components["schemas"]["EmbedToken"]["token"]>` — the embed JWT string for confirmation)
|
|
459
511
|
|
|
@@ -461,51 +513,36 @@ Renders the secure Google Pay iframe button (express checkout flow).
|
|
|
461
513
|
|
|
462
514
|
**Optional props:**
|
|
463
515
|
|
|
464
|
-
- `
|
|
465
|
-
- `
|
|
466
|
-
- `
|
|
467
|
-
- `buttonColor` (`"default" | "black" | "white"`)
|
|
468
|
-
- `buttonRadius` (`number`, 0–20)
|
|
469
|
-
- `buttonSizeMode` (`"static" | "fill"`)
|
|
470
|
-
- `buttonLocale` (`string`)
|
|
471
|
-
- `buttonBorderType` (`"no_border" | "default_border"`)
|
|
472
|
-
- `buttonStyle` — styles the Google Pay button **inside** the iframe, for example `buttonStyle={{ height: "48px" }}`
|
|
473
|
-
- `iframeStyle` — styles the host-page `<iframe>` element
|
|
474
|
-
- `style` — backward-compatible alias for `buttonStyle`; prefer the explicit name in new integrations
|
|
516
|
+
- `height` (`string`, defaults to `"48px"`) — painted button height. CSS length (e.g. `"48px"`).
|
|
517
|
+
- `buttonProps` — native Google Pay button options. Omitted fields keep `"plain"` / `"fill"`. The button fills the iframe; size the mount slot, not the button. Compact: `buttonProps={{ buttonSizeMode: "static", style: { width: "240px" } }}`.
|
|
518
|
+
- `iframeProps` — applied to the host-page `<iframe>` (e.g. `className`, `style`, `id`). Use CSS lengths with units in `style` (`{ borderRadius: "8px" }`). Amos does not ship Tailwind — `className` only works if the host page defines those classes.
|
|
475
519
|
|
|
476
520
|
```tsx
|
|
477
521
|
<AmosGooglePayButton
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
iframeStyle={{ borderRadius: "6px" }}
|
|
522
|
+
buttonProps={{ buttonType: "donate", buttonBorderType: "no_border" }}
|
|
523
|
+
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
481
524
|
// ...required props
|
|
482
525
|
/>
|
|
483
526
|
```
|
|
484
527
|
|
|
485
|
-
**Also accepts:** standard iframe props, minus `src`, `title`, `name`, `role`, `allow`, and `style`.
|
|
486
|
-
|
|
487
528
|
### `AmosApplePayButton`
|
|
488
529
|
|
|
489
530
|
Renders the secure Apple Pay iframe button (express checkout flow). Same required props and callbacks as `AmosGooglePayButton`.
|
|
490
531
|
|
|
491
|
-
**Optional visual props
|
|
532
|
+
**Optional visual props:**
|
|
492
533
|
|
|
493
|
-
- `
|
|
494
|
-
- `
|
|
495
|
-
- `
|
|
496
|
-
- `locale` (`string`, BCP 47, defaults to `"en-US"`)
|
|
497
|
-
- `buttonStyle` — forwarded to the `<apple-pay-button>` inside the iframe. Apple maps a CSS `height` onto its required custom property.
|
|
498
|
-
- `iframeStyle` — styles the host-page `<iframe>` element
|
|
499
|
-
- `style` — backward-compatible alias for `buttonStyle`
|
|
534
|
+
- `height` (`string`, defaults to `"48px"`) — painted button height. CSS length (e.g. `"48px"`). Apple ignores CSS `height`; Amos maps this for you.
|
|
535
|
+
- `buttonProps` — native `<apple-pay-button>` attributes. Omitted fields keep Apple's `black` / `plain` / `en-US`. The button fills the iframe; size the mount slot, not the button. `style.width` also updates `--apple-pay-button-width` unless you set that custom property yourself.
|
|
536
|
+
- `iframeProps` — host-page `<iframe>` chrome (same as Google Pay).
|
|
500
537
|
|
|
501
538
|
```tsx
|
|
502
539
|
<AmosApplePayButton
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
540
|
+
buttonProps={{
|
|
541
|
+
buttonstyle: "white-outline",
|
|
542
|
+
type: "buy",
|
|
543
|
+
locale: "en-GB",
|
|
544
|
+
}}
|
|
545
|
+
iframeProps={{ style: { borderRadius: "8px" } }}
|
|
509
546
|
// ...required props
|
|
510
547
|
/>
|
|
511
548
|
```
|
|
@@ -535,7 +572,7 @@ Re-exports of the same advanced helpers exposed by `@amos.com/amos-js`. Most int
|
|
|
535
572
|
- **`ref` / `iframeRef`**: for card and bank forms, pass `ref={iframeRef}` to the form component. The same `iframeRef` must be used when calling `validateForm`, `confirmPaymentIntent`, `confirmSetupIntent`, or `resetForm`. The component forwards the ref to the inner iframe.
|
|
536
573
|
- **`onResult` is not settlement proof**: `onResult` tells you when to stop waiting (e.g. dismiss a spinner). Verify payment or setup success on your backend via webhooks. On `status: "incomplete"`, unlock your UI — the customer can fix fields in the iframe and retry. Use `result.reason` (`"field_errors"` or `"validation_failed"`) to distinguish recoverable states.
|
|
537
574
|
- **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 (`confirmPaymentIntent` vs `confirmSetupIntent`). Handle both payment and setup outcomes via `onResult`.
|
|
538
|
-
- **Amount format**: for `AmosGooglePayButton` and `AmosApplePayButton`, `amount` is a string (e.g. `"
|
|
575
|
+
- **Amount format**: for `AmosGooglePayButton` and `AmosApplePayButton`, `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 `onInitiatePaymentIntentRequest`), `amount` is a number in cents (e.g. `5000`).
|
|
539
576
|
- **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.
|
|
540
577
|
- **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.
|
|
541
578
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="googlepay" />
|
|
2
|
-
import { Appearance, ApplePayButtonElementProps, BillingAddressRequirement, ConfirmationResult, CreditCardAdditionalFields, GooglePayButtonElementProps
|
|
2
|
+
import { Appearance, ApplePayButtonElementProps, BillingAddressRequirement, ConfirmationResult, CreditCardAdditionalFields, GooglePayButtonElementProps } from '@amos.com/amos-js';
|
|
3
3
|
import { components } from '@amos.com/node';
|
|
4
|
-
import { ComponentProps, RefObject } from 'react';
|
|
4
|
+
import { ComponentProps, Ref, RefObject } from 'react';
|
|
5
5
|
export * from '@amos.com/amos-js';
|
|
6
6
|
type IframeRef = RefObject<HTMLIFrameElement | null> | undefined;
|
|
7
7
|
/**
|
|
@@ -40,25 +40,8 @@ export declare function confirmSetupIntent({ iframeRef, token, }: {
|
|
|
40
40
|
export declare function resetForm({ iframeRef }: {
|
|
41
41
|
iframeRef: IframeRef;
|
|
42
42
|
}): void;
|
|
43
|
+
type ForwardedIframeRef = Ref<HTMLIFrameElement> | undefined;
|
|
43
44
|
type IframePassthroughProps = Omit<ComponentProps<"iframe">, "src" | "title" | "name" | "role" | "allow">;
|
|
44
|
-
type WalletStyleProps = {
|
|
45
|
-
/**
|
|
46
|
-
* Stretch the wallet button to fill the iframe width.
|
|
47
|
-
*
|
|
48
|
-
* @default false
|
|
49
|
-
*/
|
|
50
|
-
fullWidth?: boolean;
|
|
51
|
-
/** Styles applied to the wallet button inside the Amos iframe. */
|
|
52
|
-
buttonStyle?: WalletButtonStyle;
|
|
53
|
-
/** Styles applied to the host-page `<iframe>` element. */
|
|
54
|
-
iframeStyle?: ComponentProps<"iframe">["style"];
|
|
55
|
-
/**
|
|
56
|
-
* Styles applied to the wallet button inside the Amos iframe.
|
|
57
|
-
*
|
|
58
|
-
* @deprecated Use `buttonStyle` to distinguish it from `iframeStyle`.
|
|
59
|
-
*/
|
|
60
|
-
style?: WalletButtonStyle;
|
|
61
|
-
};
|
|
62
45
|
type AmosCreditCardPaymentMethodFormProps = IframePassthroughProps & {
|
|
63
46
|
renderToken: string;
|
|
64
47
|
appearance?: Appearance;
|
|
@@ -88,27 +71,65 @@ type AmosBankAccountPaymentMethodFormProps = IframePassthroughProps & {
|
|
|
88
71
|
billingAddressRequirement?: BillingAddressRequirement;
|
|
89
72
|
};
|
|
90
73
|
export declare function AmosBankAccountPaymentMethodForm({ ref, renderToken, appearance, onResult, onValidityChange, billingAddressRequirement, style, ...rest }: AmosBankAccountPaymentMethodFormProps): import("react").JSX.Element;
|
|
91
|
-
type AmosGooglePayButtonProps =
|
|
74
|
+
type AmosGooglePayButtonProps = {
|
|
75
|
+
ref?: ForwardedIframeRef;
|
|
92
76
|
renderToken: string;
|
|
77
|
+
/**
|
|
78
|
+
* Major-currency decimal string shown in the Google Pay sheet
|
|
79
|
+
* (e.g. `"50.00"` for $50.00). Converted to cents in
|
|
80
|
+
* `paymentIntentCreateAttributes.amount`.
|
|
81
|
+
*/
|
|
93
82
|
amount: string;
|
|
94
83
|
merchantName: string;
|
|
95
|
-
|
|
84
|
+
/**
|
|
85
|
+
* Painted button height. CSS length (e.g. `"48px"`).
|
|
86
|
+
* @default "48px"
|
|
87
|
+
*/
|
|
88
|
+
height?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Native Google Pay button attributes and inner style. Omitted
|
|
91
|
+
* fields keep Amos paint defaults (`buttonType: "plain"`,
|
|
92
|
+
* `buttonSizeMode: "fill"`). The button fills the iframe — size the
|
|
93
|
+
* mount slot, not the button.
|
|
94
|
+
*/
|
|
95
|
+
buttonProps?: GooglePayButtonElementProps;
|
|
96
|
+
/** Props applied to the host-page `<iframe>` element. */
|
|
97
|
+
iframeProps?: IframePassthroughProps;
|
|
96
98
|
onInitiatePaymentIntentRequest: ({ paymentIntentCreateAttributes, customerCreateAttributes, }: {
|
|
97
99
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
98
100
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
99
101
|
}) => Promise<components["schemas"]["EmbedToken"]["token"]>;
|
|
100
102
|
onResult: (result: ConfirmationResult) => void;
|
|
101
103
|
};
|
|
102
|
-
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName,
|
|
103
|
-
type AmosApplePayButtonProps =
|
|
104
|
+
export declare function AmosGooglePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps, onInitiatePaymentIntentRequest, onResult, }: AmosGooglePayButtonProps): import("react").JSX.Element;
|
|
105
|
+
type AmosApplePayButtonProps = {
|
|
106
|
+
ref?: ForwardedIframeRef;
|
|
104
107
|
renderToken: string;
|
|
108
|
+
/**
|
|
109
|
+
* Major-currency decimal string shown in the Apple Pay sheet
|
|
110
|
+
* (e.g. `"50.00"` for $50.00). Converted to cents in
|
|
111
|
+
* `paymentIntentCreateAttributes.amount`.
|
|
112
|
+
*/
|
|
105
113
|
amount: string;
|
|
106
114
|
merchantName: string;
|
|
107
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Painted button height. CSS length (e.g. `"48px"`). Apple ignores
|
|
117
|
+
* CSS `height`; Amos maps this for you.
|
|
118
|
+
* @default "48px"
|
|
119
|
+
*/
|
|
120
|
+
height?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Native `<apple-pay-button>` attributes and inner style. Omitted
|
|
123
|
+
* fields keep Apple's defaults (`black` / `plain` / `en-US`). The
|
|
124
|
+
* button fills the iframe — size the mount slot, not the button.
|
|
125
|
+
*/
|
|
126
|
+
buttonProps?: ApplePayButtonElementProps;
|
|
127
|
+
/** Props applied to the host-page `<iframe>` element. */
|
|
128
|
+
iframeProps?: IframePassthroughProps;
|
|
108
129
|
onInitiatePaymentIntentRequest: ({ paymentIntentCreateAttributes, customerCreateAttributes, }: {
|
|
109
130
|
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
110
131
|
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
111
132
|
}) => Promise<components["schemas"]["EmbedToken"]["token"]>;
|
|
112
133
|
onResult: (result: ConfirmationResult) => void;
|
|
113
134
|
};
|
|
114
|
-
export declare function AmosApplePayButton({ ref, renderToken, amount, merchantName,
|
|
135
|
+
export declare function AmosApplePayButton({ ref, renderToken, amount, merchantName, height, buttonProps, iframeProps, onInitiatePaymentIntentRequest, onResult, }: 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.confirmPaymentIntent)({iframe:r(t),token:n})}function o({iframeRef:t,token:n}){(0,e.confirmSetupIntent)({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(
|
|
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.confirmPaymentIntent)({iframe:r(t),token:n})}function o({iframeRef:t,token:n}){(0,e.confirmSetupIntent)({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.useEffect)(()=>{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)})}function d({ref:r,renderToken:i,appearance:a,onResult:o,onValidityChange: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,onResult:o,onValidityChange:s},remountDeps:[i,c.cardholderName,l],iframePassthrough:{style:d,...f},updateDeps:[a,c,l,o,s]}),(0,n.jsx)(`div`,{ref:p})}function f({ref:r,renderToken:i,appearance:a,onResult:o,onValidityChange:s,billingAddressRequirement:c=`country`,style:l,...d}){let f=(0,t.useRef)(null);return u({containerRef:f,iframeRef:r,mount:e.mountAmosBankAccountPaymentMethodForm,options:{renderToken:i,appearance:a,billingAddressRequirement:c,onResult:o,onValidityChange:s},remountDeps:[i,c],iframePassthrough:{style:l,...d},updateDeps:[a,c,o,s]}),(0,n.jsx)(`div`,{ref:f})}function p({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onInitiatePaymentIntentRequest:d,onResult:f}){let p=(0,t.useRef)(null);return u({containerRef:p,iframeRef:r,mount:e.mountAmosGooglePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onInitiatePaymentIntentRequest:d,onResult:f},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,d,f]}),(0,n.jsx)(`div`,{ref:p})}function m({ref:r,renderToken:i,amount:a,merchantName:o,height:s=`48px`,buttonProps:c,iframeProps:l,onInitiatePaymentIntentRequest:d,onResult:f}){let p=(0,t.useRef)(null);return u({containerRef:p,iframeRef:r,mount:e.mountAmosApplePayButton,options:{renderToken:i,amount:a,merchantName:o,height:s,buttonProps:c,onInitiatePaymentIntentRequest:d,onResult:f},remountDeps:[i],iframePassthrough:l??{},updateDeps:[a,o,s,c,d,f]}),(0,n.jsx)(`div`,{ref:p})}exports.AmosApplePayButton=m,exports.AmosBankAccountPaymentMethodForm=f,exports.AmosCreditCardPaymentMethodForm=d,exports.AmosGooglePayButton=p,exports.confirmPaymentIntent=a,exports.confirmSetupIntent=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
|
@@ -27,45 +27,29 @@ function h({ iframeRef: e }) {
|
|
|
27
27
|
function g(e, t) {
|
|
28
28
|
typeof e == "function" ? e(t) : e && (e.current = t);
|
|
29
29
|
}
|
|
30
|
-
function _(
|
|
31
|
-
|
|
32
|
-
buttonSizeMode: e ?? (n ? "fill" : void 0),
|
|
33
|
-
style: n ? {
|
|
34
|
-
width: "100%",
|
|
35
|
-
...t
|
|
36
|
-
} : t
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
function v({ style: e, fullWidth: t }) {
|
|
40
|
-
return t ? { style: {
|
|
41
|
-
"--apple-pay-button-width": "100%",
|
|
42
|
-
width: "100%",
|
|
43
|
-
...e
|
|
44
|
-
} } : { style: e };
|
|
45
|
-
}
|
|
46
|
-
function y(e, { style: t, className: n, id: r, ...i }) {
|
|
47
|
-
n != null && (e.className = n), r != null && (e.id = r), t != null && Object.assign(e.style, t);
|
|
30
|
+
function _(e, { style: t, className: n, id: r, ...i }) {
|
|
31
|
+
n != null && (e.className = n), r != null && (e.id = r), Object.assign(e.style, t);
|
|
48
32
|
for (let [t, n] of Object.entries(i)) n != null && (t in e ? Reflect.set(e, t, n) : e.setAttribute(t, String(n)));
|
|
49
33
|
}
|
|
50
|
-
function
|
|
34
|
+
function v({ containerRef: e, iframeRef: t, mount: n, options: r, remountDeps: i, iframePassthrough: a, updateDeps: o }) {
|
|
51
35
|
let s = l(null);
|
|
52
36
|
c(() => {
|
|
53
37
|
let i = e.current;
|
|
54
38
|
if (!i) return;
|
|
55
39
|
let o = n(i, r);
|
|
56
|
-
return s.current = o, g(t, o.iframe),
|
|
40
|
+
return s.current = o, g(t, o.iframe), _(o.iframe, a), () => {
|
|
57
41
|
o.destroy(), s.current = null, g(t, null);
|
|
58
42
|
};
|
|
59
43
|
}, [...i]), c(() => {
|
|
60
44
|
s.current?.update(r);
|
|
61
45
|
}, [...o]), c(() => {
|
|
62
46
|
let e = s.current?.iframe;
|
|
63
|
-
e &&
|
|
47
|
+
e && _(e, a);
|
|
64
48
|
});
|
|
65
49
|
}
|
|
66
|
-
function
|
|
50
|
+
function y({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChange: a, additionalFields: o = { cardholderName: !1 }, billingAddressRequirement: s = "country", style: c, ...d }) {
|
|
67
51
|
let f = l(null);
|
|
68
|
-
return
|
|
52
|
+
return v({
|
|
69
53
|
containerRef: f,
|
|
70
54
|
iframeRef: e,
|
|
71
55
|
mount: i,
|
|
@@ -95,9 +79,9 @@ function x({ ref: e, renderToken: t, appearance: n, onResult: r, onValidityChang
|
|
|
95
79
|
]
|
|
96
80
|
}), /* @__PURE__ */ u("div", { ref: f });
|
|
97
81
|
}
|
|
98
|
-
function
|
|
82
|
+
function b({ ref: e, renderToken: t, appearance: n, onResult: i, onValidityChange: a, billingAddressRequirement: o = "country", style: s, ...c }) {
|
|
99
83
|
let d = l(null);
|
|
100
|
-
return
|
|
84
|
+
return v({
|
|
101
85
|
containerRef: d,
|
|
102
86
|
iframeRef: e,
|
|
103
87
|
mount: r,
|
|
@@ -121,90 +105,59 @@ function S({ ref: e, renderToken: t, appearance: n, onResult: i, onValidityChang
|
|
|
121
105
|
]
|
|
122
106
|
}), /* @__PURE__ */ u("div", { ref: d });
|
|
123
107
|
}
|
|
124
|
-
function
|
|
125
|
-
let
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
fullWidth: g
|
|
129
|
-
});
|
|
130
|
-
return b({
|
|
131
|
-
containerRef: C,
|
|
108
|
+
function x({ ref: e, renderToken: t, amount: n, merchantName: r, height: i = "48px", buttonProps: o, iframeProps: s, onInitiatePaymentIntentRequest: c, onResult: d }) {
|
|
109
|
+
let f = l(null);
|
|
110
|
+
return v({
|
|
111
|
+
containerRef: f,
|
|
132
112
|
iframeRef: e,
|
|
133
113
|
mount: a,
|
|
134
114
|
options: {
|
|
135
115
|
renderToken: t,
|
|
136
116
|
amount: n,
|
|
137
117
|
merchantName: r,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
buttonColor: d,
|
|
143
|
-
buttonRadius: f,
|
|
144
|
-
buttonSizeMode: w.buttonSizeMode,
|
|
145
|
-
buttonLocale: m,
|
|
146
|
-
buttonBorderType: h,
|
|
147
|
-
style: w.style
|
|
118
|
+
height: i,
|
|
119
|
+
buttonProps: o,
|
|
120
|
+
onInitiatePaymentIntentRequest: c,
|
|
121
|
+
onResult: d
|
|
148
122
|
},
|
|
149
123
|
remountDeps: [t],
|
|
150
|
-
iframePassthrough: {
|
|
151
|
-
style: y,
|
|
152
|
-
...S
|
|
153
|
-
},
|
|
124
|
+
iframePassthrough: s ?? {},
|
|
154
125
|
updateDeps: [
|
|
155
126
|
n,
|
|
156
127
|
r,
|
|
157
128
|
i,
|
|
158
129
|
o,
|
|
159
|
-
s,
|
|
160
130
|
c,
|
|
161
|
-
d
|
|
162
|
-
f,
|
|
163
|
-
w.buttonSizeMode,
|
|
164
|
-
m,
|
|
165
|
-
h,
|
|
166
|
-
w.style
|
|
131
|
+
d
|
|
167
132
|
]
|
|
168
|
-
}), /* @__PURE__ */ u("div", { ref:
|
|
133
|
+
}), /* @__PURE__ */ u("div", { ref: f });
|
|
169
134
|
}
|
|
170
|
-
function
|
|
171
|
-
let
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
});
|
|
175
|
-
return b({
|
|
176
|
-
containerRef: y,
|
|
135
|
+
function S({ ref: e, renderToken: t, amount: r, merchantName: i, height: a = "48px", buttonProps: o, iframeProps: s, onInitiatePaymentIntentRequest: c, onResult: d }) {
|
|
136
|
+
let f = l(null);
|
|
137
|
+
return v({
|
|
138
|
+
containerRef: f,
|
|
177
139
|
iframeRef: e,
|
|
178
140
|
mount: n,
|
|
179
141
|
options: {
|
|
180
142
|
renderToken: t,
|
|
181
143
|
amount: r,
|
|
182
144
|
merchantName: i,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
type: d,
|
|
188
|
-
locale: f,
|
|
189
|
-
style: x.style
|
|
145
|
+
height: a,
|
|
146
|
+
buttonProps: o,
|
|
147
|
+
onInitiatePaymentIntentRequest: c,
|
|
148
|
+
onResult: d
|
|
190
149
|
},
|
|
191
150
|
remountDeps: [t],
|
|
192
|
-
iframePassthrough: {
|
|
193
|
-
style: h,
|
|
194
|
-
..._
|
|
195
|
-
},
|
|
151
|
+
iframePassthrough: s ?? {},
|
|
196
152
|
updateDeps: [
|
|
197
153
|
r,
|
|
198
154
|
i,
|
|
199
155
|
a,
|
|
200
156
|
o,
|
|
201
|
-
s,
|
|
202
157
|
c,
|
|
203
|
-
d
|
|
204
|
-
f,
|
|
205
|
-
x.style
|
|
158
|
+
d
|
|
206
159
|
]
|
|
207
|
-
}), /* @__PURE__ */ u("div", { ref:
|
|
160
|
+
}), /* @__PURE__ */ u("div", { ref: f });
|
|
208
161
|
}
|
|
209
162
|
//#endregion
|
|
210
|
-
export {
|
|
163
|
+
export { S as AmosApplePayButton, b as AmosBankAccountPaymentMethodForm, y as AmosCreditCardPaymentMethodForm, x as AmosGooglePayButton, p as confirmPaymentIntent, m as confirmSetupIntent, h as resetForm, f as validateForm };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amos.com/react-amos-js",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.15",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"vite-plugin-dts": "5.0.3"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@amos.com/amos-js": "0.9.
|
|
51
|
+
"@amos.com/amos-js": "0.9.16",
|
|
52
52
|
"@types/googlepay": "0.7.11"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
package/src/index.tsx
CHANGED
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
mountAmosBankAccountPaymentMethodForm,
|
|
16
16
|
mountAmosCreditCardPaymentMethodForm,
|
|
17
17
|
mountAmosGooglePayButton,
|
|
18
|
-
type WalletButtonStyle,
|
|
19
18
|
} from "@amos.com/amos-js";
|
|
20
19
|
import type { components } from "@amos.com/node";
|
|
21
20
|
import {
|
|
@@ -109,59 +108,6 @@ type IframePassthroughProps = Omit<
|
|
|
109
108
|
"src" | "title" | "name" | "role" | "allow"
|
|
110
109
|
>;
|
|
111
110
|
|
|
112
|
-
type WalletStyleProps = {
|
|
113
|
-
/**
|
|
114
|
-
* Stretch the wallet button to fill the iframe width.
|
|
115
|
-
*
|
|
116
|
-
* @default false
|
|
117
|
-
*/
|
|
118
|
-
fullWidth?: boolean;
|
|
119
|
-
/** Styles applied to the wallet button inside the Amos iframe. */
|
|
120
|
-
buttonStyle?: WalletButtonStyle;
|
|
121
|
-
/** Styles applied to the host-page `<iframe>` element. */
|
|
122
|
-
iframeStyle?: ComponentProps<"iframe">["style"];
|
|
123
|
-
/**
|
|
124
|
-
* Styles applied to the wallet button inside the Amos iframe.
|
|
125
|
-
*
|
|
126
|
-
* @deprecated Use `buttonStyle` to distinguish it from `iframeStyle`.
|
|
127
|
-
*/
|
|
128
|
-
style?: WalletButtonStyle;
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
function resolveGooglePayButtonLayout({
|
|
132
|
-
buttonSizeMode,
|
|
133
|
-
style,
|
|
134
|
-
fullWidth,
|
|
135
|
-
}: {
|
|
136
|
-
buttonSizeMode?: GooglePayButtonElementProps["buttonSizeMode"];
|
|
137
|
-
style?: WalletButtonStyle;
|
|
138
|
-
fullWidth: boolean;
|
|
139
|
-
}): Pick<GooglePayButtonElementProps, "buttonSizeMode" | "style"> {
|
|
140
|
-
return {
|
|
141
|
-
buttonSizeMode: buttonSizeMode ?? (fullWidth ? "fill" : undefined),
|
|
142
|
-
style: fullWidth ? { width: "100%", ...style } : style,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function resolveApplePayButtonLayout({
|
|
147
|
-
style,
|
|
148
|
-
fullWidth,
|
|
149
|
-
}: {
|
|
150
|
-
style?: WalletButtonStyle;
|
|
151
|
-
fullWidth: boolean;
|
|
152
|
-
}): Pick<ApplePayButtonElementProps, "style"> {
|
|
153
|
-
if (!fullWidth) {
|
|
154
|
-
return { style };
|
|
155
|
-
}
|
|
156
|
-
return {
|
|
157
|
-
style: {
|
|
158
|
-
"--apple-pay-button-width": "100%",
|
|
159
|
-
width: "100%",
|
|
160
|
-
...style,
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
111
|
function applyIframePassthrough(
|
|
166
112
|
iframe: HTMLIFrameElement,
|
|
167
113
|
{ style, className, id, ...rest }: IframePassthroughProps,
|
|
@@ -172,9 +118,7 @@ function applyIframePassthrough(
|
|
|
172
118
|
if (id != null) {
|
|
173
119
|
iframe.id = id;
|
|
174
120
|
}
|
|
175
|
-
|
|
176
|
-
Object.assign(iframe.style, style);
|
|
177
|
-
}
|
|
121
|
+
Object.assign(iframe.style, style);
|
|
178
122
|
for (const [key, value] of Object.entries(rest)) {
|
|
179
123
|
if (value == null) {
|
|
180
124
|
continue;
|
|
@@ -348,50 +292,52 @@ export function AmosBankAccountPaymentMethodForm({
|
|
|
348
292
|
return <div ref={containerRef} />;
|
|
349
293
|
}
|
|
350
294
|
|
|
351
|
-
type AmosGooglePayButtonProps =
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
295
|
+
type AmosGooglePayButtonProps = {
|
|
296
|
+
ref?: ForwardedIframeRef;
|
|
297
|
+
renderToken: string;
|
|
298
|
+
/**
|
|
299
|
+
* Major-currency decimal string shown in the Google Pay sheet
|
|
300
|
+
* (e.g. `"50.00"` for $50.00). Converted to cents in
|
|
301
|
+
* `paymentIntentCreateAttributes.amount`.
|
|
302
|
+
*/
|
|
303
|
+
amount: string;
|
|
304
|
+
merchantName: string;
|
|
305
|
+
/**
|
|
306
|
+
* Painted button height. CSS length (e.g. `"48px"`).
|
|
307
|
+
* @default "48px"
|
|
308
|
+
*/
|
|
309
|
+
height?: string;
|
|
310
|
+
/**
|
|
311
|
+
* Native Google Pay button attributes and inner style. Omitted
|
|
312
|
+
* fields keep Amos paint defaults (`buttonType: "plain"`,
|
|
313
|
+
* `buttonSizeMode: "fill"`). The button fills the iframe — size the
|
|
314
|
+
* mount slot, not the button.
|
|
315
|
+
*/
|
|
316
|
+
buttonProps?: GooglePayButtonElementProps;
|
|
317
|
+
/** Props applied to the host-page `<iframe>` element. */
|
|
318
|
+
iframeProps?: IframePassthroughProps;
|
|
319
|
+
onInitiatePaymentIntentRequest: ({
|
|
320
|
+
paymentIntentCreateAttributes,
|
|
321
|
+
customerCreateAttributes,
|
|
322
|
+
}: {
|
|
323
|
+
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
324
|
+
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
325
|
+
}) => Promise<components["schemas"]["EmbedToken"]["token"]>;
|
|
326
|
+
onResult: (result: ConfirmationResult) => void;
|
|
327
|
+
};
|
|
367
328
|
|
|
368
329
|
export function AmosGooglePayButton({
|
|
369
330
|
ref,
|
|
370
331
|
renderToken,
|
|
371
332
|
amount,
|
|
372
333
|
merchantName,
|
|
373
|
-
|
|
334
|
+
height = "48px",
|
|
335
|
+
buttonProps,
|
|
336
|
+
iframeProps,
|
|
374
337
|
onInitiatePaymentIntentRequest,
|
|
375
338
|
onResult,
|
|
376
|
-
buttonType,
|
|
377
|
-
buttonColor,
|
|
378
|
-
buttonRadius,
|
|
379
|
-
buttonSizeMode,
|
|
380
|
-
buttonLocale,
|
|
381
|
-
buttonBorderType,
|
|
382
|
-
fullWidth = false,
|
|
383
|
-
buttonStyle,
|
|
384
|
-
iframeStyle,
|
|
385
|
-
style,
|
|
386
|
-
...rest
|
|
387
339
|
}: AmosGooglePayButtonProps) {
|
|
388
340
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
389
|
-
const resolvedStyle = buttonStyle ?? style;
|
|
390
|
-
const layout = resolveGooglePayButtonLayout({
|
|
391
|
-
buttonSizeMode,
|
|
392
|
-
style: resolvedStyle,
|
|
393
|
-
fullWidth,
|
|
394
|
-
});
|
|
395
341
|
|
|
396
342
|
useAmosEmbed({
|
|
397
343
|
containerRef,
|
|
@@ -401,78 +347,72 @@ export function AmosGooglePayButton({
|
|
|
401
347
|
renderToken,
|
|
402
348
|
amount,
|
|
403
349
|
merchantName,
|
|
404
|
-
|
|
350
|
+
height,
|
|
351
|
+
buttonProps,
|
|
405
352
|
onInitiatePaymentIntentRequest,
|
|
406
353
|
onResult,
|
|
407
|
-
buttonType,
|
|
408
|
-
buttonColor,
|
|
409
|
-
buttonRadius,
|
|
410
|
-
buttonSizeMode: layout.buttonSizeMode,
|
|
411
|
-
buttonLocale,
|
|
412
|
-
buttonBorderType,
|
|
413
|
-
style: layout.style,
|
|
414
354
|
},
|
|
415
355
|
remountDeps: [renderToken],
|
|
416
|
-
iframePassthrough:
|
|
356
|
+
iframePassthrough: iframeProps ?? {},
|
|
417
357
|
updateDeps: [
|
|
418
358
|
amount,
|
|
419
359
|
merchantName,
|
|
420
|
-
|
|
360
|
+
height,
|
|
361
|
+
buttonProps,
|
|
421
362
|
onInitiatePaymentIntentRequest,
|
|
422
363
|
onResult,
|
|
423
|
-
buttonType,
|
|
424
|
-
buttonColor,
|
|
425
|
-
buttonRadius,
|
|
426
|
-
layout.buttonSizeMode,
|
|
427
|
-
buttonLocale,
|
|
428
|
-
buttonBorderType,
|
|
429
|
-
layout.style,
|
|
430
364
|
],
|
|
431
365
|
});
|
|
432
366
|
|
|
433
367
|
return <div ref={containerRef} />;
|
|
434
368
|
}
|
|
435
369
|
|
|
436
|
-
type AmosApplePayButtonProps =
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
370
|
+
type AmosApplePayButtonProps = {
|
|
371
|
+
ref?: ForwardedIframeRef;
|
|
372
|
+
renderToken: string;
|
|
373
|
+
/**
|
|
374
|
+
* Major-currency decimal string shown in the Apple Pay sheet
|
|
375
|
+
* (e.g. `"50.00"` for $50.00). Converted to cents in
|
|
376
|
+
* `paymentIntentCreateAttributes.amount`.
|
|
377
|
+
*/
|
|
378
|
+
amount: string;
|
|
379
|
+
merchantName: string;
|
|
380
|
+
/**
|
|
381
|
+
* Painted button height. CSS length (e.g. `"48px"`). Apple ignores
|
|
382
|
+
* CSS `height`; Amos maps this for you.
|
|
383
|
+
* @default "48px"
|
|
384
|
+
*/
|
|
385
|
+
height?: string;
|
|
386
|
+
/**
|
|
387
|
+
* Native `<apple-pay-button>` attributes and inner style. Omitted
|
|
388
|
+
* fields keep Apple's defaults (`black` / `plain` / `en-US`). The
|
|
389
|
+
* button fills the iframe — size the mount slot, not the button.
|
|
390
|
+
*/
|
|
391
|
+
buttonProps?: ApplePayButtonElementProps;
|
|
392
|
+
/** Props applied to the host-page `<iframe>` element. */
|
|
393
|
+
iframeProps?: IframePassthroughProps;
|
|
394
|
+
onInitiatePaymentIntentRequest: ({
|
|
395
|
+
paymentIntentCreateAttributes,
|
|
396
|
+
customerCreateAttributes,
|
|
397
|
+
}: {
|
|
398
|
+
paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"];
|
|
399
|
+
customerCreateAttributes: components["schemas"]["CreateCustomerInput"];
|
|
400
|
+
}) => Promise<components["schemas"]["EmbedToken"]["token"]>;
|
|
401
|
+
onResult: (result: ConfirmationResult) => void;
|
|
402
|
+
};
|
|
452
403
|
|
|
453
404
|
export function AmosApplePayButton({
|
|
454
405
|
ref,
|
|
455
406
|
renderToken,
|
|
456
407
|
amount,
|
|
457
408
|
merchantName,
|
|
458
|
-
|
|
409
|
+
height = "48px",
|
|
410
|
+
buttonProps,
|
|
411
|
+
iframeProps,
|
|
459
412
|
onInitiatePaymentIntentRequest,
|
|
460
413
|
onResult,
|
|
461
|
-
buttonstyle,
|
|
462
|
-
type,
|
|
463
|
-
locale,
|
|
464
|
-
fullWidth = false,
|
|
465
|
-
buttonStyle,
|
|
466
|
-
iframeStyle,
|
|
467
|
-
style,
|
|
468
|
-
...rest
|
|
469
414
|
}: AmosApplePayButtonProps) {
|
|
470
415
|
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
471
|
-
const resolvedStyle = buttonStyle ?? style;
|
|
472
|
-
const layout = resolveApplePayButtonLayout({
|
|
473
|
-
style: resolvedStyle,
|
|
474
|
-
fullWidth,
|
|
475
|
-
});
|
|
476
416
|
|
|
477
417
|
useAmosEmbed({
|
|
478
418
|
containerRef,
|
|
@@ -482,26 +422,20 @@ export function AmosApplePayButton({
|
|
|
482
422
|
renderToken,
|
|
483
423
|
amount,
|
|
484
424
|
merchantName,
|
|
485
|
-
|
|
425
|
+
height,
|
|
426
|
+
buttonProps,
|
|
486
427
|
onInitiatePaymentIntentRequest,
|
|
487
428
|
onResult,
|
|
488
|
-
buttonstyle,
|
|
489
|
-
type,
|
|
490
|
-
locale,
|
|
491
|
-
style: layout.style,
|
|
492
429
|
},
|
|
493
430
|
remountDeps: [renderToken],
|
|
494
|
-
iframePassthrough:
|
|
431
|
+
iframePassthrough: iframeProps ?? {},
|
|
495
432
|
updateDeps: [
|
|
496
433
|
amount,
|
|
497
434
|
merchantName,
|
|
498
|
-
|
|
435
|
+
height,
|
|
436
|
+
buttonProps,
|
|
499
437
|
onInitiatePaymentIntentRequest,
|
|
500
438
|
onResult,
|
|
501
|
-
buttonstyle,
|
|
502
|
-
type,
|
|
503
|
-
locale,
|
|
504
|
-
layout.style,
|
|
505
439
|
],
|
|
506
440
|
});
|
|
507
441
|
|