@amos.com/react-amos-js 0.9.14 → 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 CHANGED
@@ -247,58 +247,109 @@ function CheckoutForm() {
247
247
  }
248
248
  ```
249
249
 
250
- ### Rendering Google Pay within your checkout flow
250
+ ### Rendering Google Pay and Apple Pay within your checkout flow
251
251
 
252
252
  ```tsx
253
253
  import { useState } from "react";
254
- import { AmosGooglePayButton } from "@amos.com/react-amos-js";
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
+ }
255
282
 
256
- function CheckoutGooglePay() {
283
+ function CheckoutWallets({ renderToken }: { renderToken: string }) {
257
284
  const [error, setError] = useState<string | null>(null);
258
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
+
259
296
  return (
260
297
  <>
261
- <AmosGooglePayButton
262
- renderToken="the-render-token-that-you-created-on-dashboard.amos.com"
263
- amount="5000" // $50.00 in cents, as a string
264
- merchantName="your-user-facing-merchant-name"
265
- onInitiatePaymentIntentRequest={async ({
266
- paymentIntentCreateAttributes,
267
- customerCreateAttributes,
268
- }) => {
269
- const response = await fetch("/api/payment-intents", {
270
- method: "POST",
271
- headers: { "Content-Type": "application/json" },
272
- body: JSON.stringify({
273
- customer: customerCreateAttributes,
274
- paymentIntent: paymentIntentCreateAttributes,
275
- }),
276
- });
277
-
278
- if (!response.ok) {
279
- throw new Error("Failed to create payment intent.");
280
- }
281
-
282
- const { token } = await response.json();
283
- return token;
284
- }}
285
- onResult={(result) => {
286
- if (result.status === "succeeded") {
287
- console.log("Confirm returned:", result);
288
- } else if (result.status === "failed") {
289
- console.error("Confirm failed:", result.errorMessage);
290
- } else if (result.status === "incomplete") {
291
- console.log("Recoverable:", result.reason);
292
- }
293
- }}
294
- />
295
- {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}
296
319
  </>
297
320
  );
298
321
  }
299
322
  ```
300
323
 
301
- `AmosApplePayButton` uses the same props and express-checkout callbacks. Drop it in the same place (or alongside Google Pay) with the same `amount`, `merchantName`, and `onInitiatePaymentIntentRequest` wiring. On Safari, the native payment sheet is used; 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 on your page with a **Cancel payment** button.
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
+ ```
302
353
 
303
354
  ### Saving a payment method with setup intent (credit card)
304
355
 
@@ -454,7 +505,7 @@ Renders the secure Google Pay iframe button (express checkout flow).
454
505
  **Required props:**
455
506
 
456
507
  - `renderToken` (`string`)
457
- - `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`.
458
509
  - `merchantName` (`string`)
459
510
  - `onInitiatePaymentIntentRequest` (callback receiving `{ paymentIntentCreateAttributes: components["schemas"]["CreatePaymentIntentInput"]; customerCreateAttributes: components["schemas"]["CreateCustomerInput"] }`, returns `Promise<components["schemas"]["EmbedToken"]["token"]>` — the embed JWT string for confirmation)
460
511
 
@@ -521,7 +572,7 @@ Re-exports of the same advanced helpers exposed by `@amos.com/amos-js`. Most int
521
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.
522
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.
523
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`.
524
- - **Amount format**: for `AmosGooglePayButton` and `AmosApplePayButton`, `amount` is a string (e.g. `"5000"` for $50.00). For `components["schemas"]["CreatePaymentIntentInput"]` on the server, `amount` is a number in cents (e.g. `5000`).
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`).
525
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.
526
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.
527
578
 
package/dist/index.d.ts CHANGED
@@ -74,6 +74,11 @@ export declare function AmosBankAccountPaymentMethodForm({ ref, renderToken, app
74
74
  type AmosGooglePayButtonProps = {
75
75
  ref?: ForwardedIframeRef;
76
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
+ */
77
82
  amount: string;
78
83
  merchantName: string;
79
84
  /**
@@ -100,6 +105,11 @@ export declare function AmosGooglePayButton({ ref, renderToken, amount, merchant
100
105
  type AmosApplePayButtonProps = {
101
106
  ref?: ForwardedIframeRef;
102
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
+ */
103
113
  amount: string;
104
114
  merchantName: string;
105
115
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amos.com/react-amos-js",
3
- "version": "0.9.14",
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.15",
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
@@ -295,6 +295,11 @@ export function AmosBankAccountPaymentMethodForm({
295
295
  type AmosGooglePayButtonProps = {
296
296
  ref?: ForwardedIframeRef;
297
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
+ */
298
303
  amount: string;
299
304
  merchantName: string;
300
305
  /**
@@ -365,6 +370,11 @@ export function AmosGooglePayButton({
365
370
  type AmosApplePayButtonProps = {
366
371
  ref?: ForwardedIframeRef;
367
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
+ */
368
378
  amount: string;
369
379
  merchantName: string;
370
380
  /**