@amos.com/amos-js 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +295 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +422 -0
- package/dist/src/google-pay.d.ts +105 -0
- package/dist/src/index.d.ts +52 -0
- package/dist/src/jwt.d.ts +16 -0
- package/dist/src/messaging.d.ts +73 -0
- package/dist/src/mount.d.ts +95 -0
- package/dist/src/payment-method-form.d.ts +90 -0
- package/dist/src/types.d.ts +64 -0
- package/package.json +47 -0
- package/src/google-pay.ts +234 -0
- package/src/index.ts +101 -0
- package/src/jwt.ts +44 -0
- package/src/messaging.ts +175 -0
- package/src/mount.ts +278 -0
- package/src/payment-method-form.ts +180 -0
- package/src/types.ts +171 -0
package/README.md
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Amos JavaScript SDK
|
|
2
|
+
|
|
3
|
+
`@amos.com/amos-js` is a framework-agnostic JavaScript SDK for embedding Amos payment methods (credit card, bank account, Google Pay) into your web app via secure iframes, and for communicating with those iframes from the host page.
|
|
4
|
+
|
|
5
|
+
It is the foundation for `@amos.com/react-amos-js`, but is fully usable on its own from vanilla JavaScript / TypeScript / any other framework.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install github:amos/amos-js
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## What it gives you
|
|
14
|
+
|
|
15
|
+
- **Types** for the `postMessage` protocol used between your page and the Amos iframe (`Message`, `Appearance`, `ThemeVariable`), plus convenience aliases for the OpenAPI schema types you'll encounter (`PaymentIntent`, `SetupIntent`, `EmbedToken`, `CreatePaymentIntentInput`, ...).
|
|
16
|
+
- **Iframe-targeted helpers** to validate the form, confirm a payment intent, confirm a setup intent, update appearance, etc.
|
|
17
|
+
- **Mount functions** (`mountAmosCreditCardPaymentMethodForm`, `mountAmosBankAccountPaymentMethodForm`, `mountAmosGooglePayButton`) that create the iframe, wire up its message protocol, manage its height/opacity, and return a small controller for updating options and tearing it down.
|
|
18
|
+
- **Lower-level building blocks** (`getCreditCardFormSrc`, `attachPaymentMethodFormListeners`, `attachGooglePayButtonListeners`, ...) for integrators (such as `@amos.com/react-amos-js`) that want to render the iframe element themselves.
|
|
19
|
+
|
|
20
|
+
> **Note:** A server-side SDK (for example `@amos.com/node`) must be used alongside `@amos.com/amos-js` for end-to-end payment processing. `@amos.com/amos-js` is the client-side half.
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
1. Render token (created on dashboard.amos.com, safe to expose to clients)
|
|
26
|
+
2. Amos API key (created on dashboard.amos.com, do not expose this to clients)
|
|
27
|
+
3. Amos account ID (provided once your application has been approved)
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
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
|
+
|
|
32
|
+
> **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.
|
|
33
|
+
|
|
34
|
+
## Quick start: credit-card form (vanilla)
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import {
|
|
38
|
+
mountAmosCreditCardPaymentMethodForm,
|
|
39
|
+
validateForm,
|
|
40
|
+
confirmPaymentIntent,
|
|
41
|
+
} from "@amos.com/amos-js";
|
|
42
|
+
|
|
43
|
+
const form = mountAmosCreditCardPaymentMethodForm(
|
|
44
|
+
document.querySelector("#card-form")!,
|
|
45
|
+
{
|
|
46
|
+
renderToken: "the-render-token-created-on-dashboard.amos.com",
|
|
47
|
+
additionalFields: { cardholderName: true },
|
|
48
|
+
appearance: {
|
|
49
|
+
themeVariables: {
|
|
50
|
+
"--primary": "oklch(0.5 0.2 240)",
|
|
51
|
+
"--radius": "0.5rem",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
onPaymentIntentConfirmationSucceeded: (paymentIntent) => {
|
|
55
|
+
console.log("Payment succeeded:", paymentIntent.id);
|
|
56
|
+
},
|
|
57
|
+
onConfirmationFailed: (errorMessage) => {
|
|
58
|
+
console.error("Payment failed:", errorMessage);
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
document.querySelector("#pay-now")!.addEventListener("click", async () => {
|
|
64
|
+
const isValid = await validateForm({ iframe: form.iframe });
|
|
65
|
+
if (!isValid) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const response = await fetch("/api/payment-intents", { method: "POST" });
|
|
70
|
+
const { token } = await response.json();
|
|
71
|
+
confirmPaymentIntent({ iframe: form.iframe, token });
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Later, if your theme changes:
|
|
75
|
+
form.update({
|
|
76
|
+
appearance: { themeVariables: { "--primary": "oklch(0.6 0.2 30)" } },
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// On teardown:
|
|
80
|
+
form.destroy();
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Understanding the flow for creating and confirming payment intents
|
|
84
|
+
|
|
85
|
+
### Credit Card & Bank Account
|
|
86
|
+
|
|
87
|
+
The following flow is for credit card and bank account payment method types only.
|
|
88
|
+
|
|
89
|
+
1. **Set up prerequisites**: create a `renderToken` (safe for client), and keep `apiKey` and `accountId` server-side only.
|
|
90
|
+
2. **Render your checkout UI** by calling `mountAmosCreditCardPaymentMethodForm(container, options)` (or `mountAmosBankAccountPaymentMethodForm(...)`) along with the required option (`onConfirmationFailed`) and optional callbacks (`onPaymentIntentConfirmationSucceeded`, `onSetupIntentConfirmationSucceeded`). The iframe height is auto-managed by the SDK.
|
|
91
|
+
3. **User clicks "Pay now" button**: call `validateForm({ iframe: form.iframe })`, which returns `Promise<true>` if the embedded form is valid, and `Promise<false>` otherwise.
|
|
92
|
+
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.
|
|
93
|
+
5. **Return the payment intent token to the browser**: your backend responds with the `EmbedToken` needed for confirmation.
|
|
94
|
+
6. **Confirm the payment intent from the client**: call `confirmPaymentIntent({ iframe: form.iframe, token })` in the browser to continue the payment flow.
|
|
95
|
+
7. **Handle UX**: show the user a "processing" state when the "Pay now" button is clicked, and show a success or error message via `onPaymentIntentConfirmationSucceeded` and `onConfirmationFailed`.
|
|
96
|
+
|
|
97
|
+
### Google Pay
|
|
98
|
+
|
|
99
|
+
Google Pay (and soon, Apple Pay) is a form of express checkout. The Google Pay button is an alternative to the "Pay now" button in your payment forms. Users can make a payment with either flow.
|
|
100
|
+
|
|
101
|
+
The key differences between the express and non-express payment flows are:
|
|
102
|
+
|
|
103
|
+
- The express payment method components accept an option called `onInitiatePaymentIntentRequest` which will be called when you should create the payment intent on your server.
|
|
104
|
+
- You do not call `validateForm` in an express flow.
|
|
105
|
+
- You do not call `confirmPaymentIntent` in an express flow (this is done after `onInitiatePaymentIntentRequest` returns a token).
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { mountAmosGooglePayButton } from "@amos.com/amos-js";
|
|
109
|
+
|
|
110
|
+
const button = mountAmosGooglePayButton(
|
|
111
|
+
document.querySelector("#google-pay")!,
|
|
112
|
+
{
|
|
113
|
+
renderToken: "the-render-token-created-on-dashboard.amos.com",
|
|
114
|
+
amount: "5000", // $50.00 in cents, as a string
|
|
115
|
+
merchantName: "your-user-facing-merchant-name",
|
|
116
|
+
onInitiatePaymentIntentRequest: async ({
|
|
117
|
+
paymentIntentCreateAttributes,
|
|
118
|
+
customerCreateAttributes,
|
|
119
|
+
}) => {
|
|
120
|
+
const response = await fetch("/api/payment-intents", {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: { "Content-Type": "application/json" },
|
|
123
|
+
body: JSON.stringify({
|
|
124
|
+
customer: customerCreateAttributes,
|
|
125
|
+
paymentIntent: paymentIntentCreateAttributes,
|
|
126
|
+
}),
|
|
127
|
+
});
|
|
128
|
+
const { token } = await response.json();
|
|
129
|
+
return token;
|
|
130
|
+
},
|
|
131
|
+
onPaymentIntentConfirmationSucceeded: (paymentIntent) => {
|
|
132
|
+
console.log("Google Pay succeeded:", paymentIntent.id);
|
|
133
|
+
},
|
|
134
|
+
onConfirmationFailed: (errorMessage) => {
|
|
135
|
+
console.error("Google Pay failed:", errorMessage);
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
// Updating amount/merchant name later just works:
|
|
141
|
+
button.update({ amount: "7500" });
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Understanding the flow for creating and confirming setup intents
|
|
145
|
+
|
|
146
|
+
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:
|
|
147
|
+
|
|
148
|
+
- On the server, call `POST /setup_intents` instead of `POST /payment_intents`.
|
|
149
|
+
- On the client, call `confirmSetupIntent({ iframe, token })` instead of `confirmPaymentIntent({ iframe, token })`.
|
|
150
|
+
- Use `onSetupIntentConfirmationSucceeded` instead of `onPaymentIntentConfirmationSucceeded`.
|
|
151
|
+
|
|
152
|
+
The same `mountAmosCreditCardPaymentMethodForm` / `mountAmosBankAccountPaymentMethodForm` controllers support both payment intents and setup intents — they are differentiated by which confirmation function you call.
|
|
153
|
+
|
|
154
|
+
## Understanding PCI DSS compliance requirements
|
|
155
|
+
|
|
156
|
+
The flows above are designed so your systems and any third-party servers you control do not handle card or bank account data in either raw or encrypted form.
|
|
157
|
+
|
|
158
|
+
Why this matters:
|
|
159
|
+
|
|
160
|
+
- The payment method UI is rendered inside Amos-hosted iframes, so sensitive input fields are not part of your DOM.
|
|
161
|
+
- Raw payment details are submitted from the iframe directly to Amos-controlled infrastructure.
|
|
162
|
+
- Your backend only creates payment intents (or setup intents) and returns a short-lived token used to continue the iframe flow.
|
|
163
|
+
- `confirmPaymentIntent` / `confirmSetupIntent` sends the token back to the iframe to complete confirmation; it does not pass full payment method payloads through your app server.
|
|
164
|
+
- In express flows (e.g. Google Pay), the iframe component handles payment data exchange and only asks your server to create a payment intent token.
|
|
165
|
+
|
|
166
|
+
In short, your app orchestrates the payment flow, while sensitive payment data stays within Amos-controlled components and APIs.
|
|
167
|
+
|
|
168
|
+
## Appearance
|
|
169
|
+
|
|
170
|
+
Every mount function (and the `attach*Listeners` helpers) accepts an optional `appearance` option 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. You can update appearance after page load via the controller's `update({ appearance })` method.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
form.update({
|
|
174
|
+
appearance: {
|
|
175
|
+
themeVariables: {
|
|
176
|
+
"--primary": "oklch(0.5 0.2 240)",
|
|
177
|
+
"--radius": "0.25rem",
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Only the variables you provide are sent; omitted variables keep their defaults.
|
|
184
|
+
|
|
185
|
+
### Available theme variables
|
|
186
|
+
|
|
187
|
+
| Variable | Purpose | Default |
|
|
188
|
+
| ------------------------ | ---------------------------------------------- | --------------------------- |
|
|
189
|
+
| `--background` | Page body and base surface color | `oklch(1 0 0)` |
|
|
190
|
+
| `--foreground` | Default text color | `oklch(0.145 0 0)` |
|
|
191
|
+
| `--primary` | Button fill and input text-selection highlight | `oklch(0.205 0 0)` |
|
|
192
|
+
| `--primary-foreground` | Text on primary-colored surfaces | `oklch(0.985 0 0)` |
|
|
193
|
+
| `--secondary` | Secondary button fill | `oklch(0.97 0 0)` |
|
|
194
|
+
| `--secondary-foreground` | Text on secondary-colored surfaces | `oklch(0.205 0 0)` |
|
|
195
|
+
| `--muted-foreground` | Placeholder text, helper labels, muted icons | `oklch(0.556 0 0)` |
|
|
196
|
+
| `--accent` | Hover/focus highlight for interactive items | `oklch(0.97 0 0)` |
|
|
197
|
+
| `--accent-foreground` | Text on accent-highlighted items | `oklch(0.205 0 0)` |
|
|
198
|
+
| `--destructive` | Error/invalid state borders and icons | `oklch(0.577 0.245 27.325)` |
|
|
199
|
+
| `--border` | General border color | `oklch(0.922 0 0)` |
|
|
200
|
+
| `--input` | Input field border color | `oklch(0.922 0 0)` |
|
|
201
|
+
| `--ring` | Focus ring and outline color | `oklch(0.708 0 0)` |
|
|
202
|
+
| `--radius` | Base border-radius (derived into sm/md/lg/xl) | `0.625rem` |
|
|
203
|
+
|
|
204
|
+
## API reference
|
|
205
|
+
|
|
206
|
+
### `mountAmosCreditCardPaymentMethodForm(container, options)`
|
|
207
|
+
|
|
208
|
+
Mount the secure credit-card payment method form into a container element (an `HTMLElement` or a CSS selector string).
|
|
209
|
+
|
|
210
|
+
**Required `options`:**
|
|
211
|
+
|
|
212
|
+
- `renderToken` (`string`)
|
|
213
|
+
- `onConfirmationFailed` (`(errorMessage: string) => void`)
|
|
214
|
+
|
|
215
|
+
**Optional `options`:**
|
|
216
|
+
|
|
217
|
+
- `appearance` (`{ themeVariables?: Partial<Record<ThemeVariable, string>> }`)
|
|
218
|
+
- `additionalFields` (`{ cardholderName: boolean }`, defaults to `{ cardholderName: false }`)
|
|
219
|
+
- `onPaymentIntentConfirmationSucceeded` (`(paymentIntent: PaymentIntent) => void`)
|
|
220
|
+
- `onSetupIntentConfirmationSucceeded` (`(setupIntent: SetupIntent) => void`)
|
|
221
|
+
- `onHeightChange`, `onAppearanceReady` (advanced — override the default iframe styling logic)
|
|
222
|
+
|
|
223
|
+
**Returns** `AmosPaymentMethodFormMountController`:
|
|
224
|
+
|
|
225
|
+
- `iframe` — the underlying `<iframe>` element.
|
|
226
|
+
- `update(patch)` — patch any of the options listed above.
|
|
227
|
+
- `destroy()` — remove the iframe and detach listeners.
|
|
228
|
+
|
|
229
|
+
### `mountAmosBankAccountPaymentMethodForm(container, options)`
|
|
230
|
+
|
|
231
|
+
Same shape as `mountAmosCreditCardPaymentMethodForm`, minus `additionalFields`.
|
|
232
|
+
|
|
233
|
+
### `mountAmosGooglePayButton(container, options)`
|
|
234
|
+
|
|
235
|
+
Mount the secure Google Pay button (express checkout) into a container element.
|
|
236
|
+
|
|
237
|
+
**Required `options`:**
|
|
238
|
+
|
|
239
|
+
- `renderToken` (`string`)
|
|
240
|
+
- `amount` (`string`)
|
|
241
|
+
- `merchantName` (`string`)
|
|
242
|
+
- `onInitiatePaymentIntentRequest` (`({ paymentIntentCreateAttributes, customerCreateAttributes }) => Promise<EmbedToken["token"]>`)
|
|
243
|
+
- `onPaymentIntentConfirmationSucceeded` (`(paymentIntent: PaymentIntent) => void`)
|
|
244
|
+
- `onConfirmationFailed` (`(errorMessage: string) => void`)
|
|
245
|
+
|
|
246
|
+
**Optional `options`:** `appearance`, `onHeightChange`, `onAppearanceReady`.
|
|
247
|
+
|
|
248
|
+
**Returns** `AmosGooglePayButtonMountController`:
|
|
249
|
+
|
|
250
|
+
- `iframe`, `update(patch)`, `destroy()`. Use `update({ amount, merchantName })` to push new values into the iframe.
|
|
251
|
+
|
|
252
|
+
### `validateForm({ iframe })`
|
|
253
|
+
|
|
254
|
+
Validates the embedded card/bank iframe form. Returns `Promise<boolean>` (resolves to `false` after 5 seconds if the iframe does not respond).
|
|
255
|
+
|
|
256
|
+
### `confirmPaymentIntent({ iframe, token })` / `confirmSetupIntent({ iframe, token })`
|
|
257
|
+
|
|
258
|
+
Forward an embed JWT to the iframe so it can complete the payment / setup intent confirmation. The matching `payment_intent_id` / `setup_intent_id` is extracted from the JWT and forwarded automatically.
|
|
259
|
+
|
|
260
|
+
### `attachPaymentMethodFormListeners(iframe, options)`
|
|
261
|
+
|
|
262
|
+
Lower-level helper that wires up the host-page side of the credit-card or bank-account iframe message protocol on an existing `<iframe>` element. The iframe is expected to have been added to the DOM with the correct `src` already (see `getCreditCardFormSrc` / `getBankAccountFormSrc`). Returns `{ update, destroy }`.
|
|
263
|
+
|
|
264
|
+
This is what `@amos.com/react-amos-js` uses to integrate with React's rendering model.
|
|
265
|
+
|
|
266
|
+
### `attachGooglePayButtonListeners(iframe, options)`
|
|
267
|
+
|
|
268
|
+
The Google Pay equivalent of `attachPaymentMethodFormListeners`.
|
|
269
|
+
|
|
270
|
+
### `getCreditCardFormSrc(renderToken, additionalFields?)` / `getBankAccountFormSrc(renderToken)` / `getGooglePayButtonSrc(renderToken)`
|
|
271
|
+
|
|
272
|
+
Build the iframe `src` URL for each form type.
|
|
273
|
+
|
|
274
|
+
### `formatGooglePayPaymentData({ paymentData })`
|
|
275
|
+
|
|
276
|
+
Transforms raw Google Pay payment data into an Amos-compatible `paymentMethod` payload. Use this when integrating with the raw Google Pay API (e.g. `@google-pay/button-react`) instead of `mountAmosGooglePayButton`.
|
|
277
|
+
|
|
278
|
+
### `createMessage(message)` / `decodeJwt(token)` / `getEmbedOrigin(renderToken)`
|
|
279
|
+
|
|
280
|
+
Advanced helpers exposed for integrators that need to construct or inspect the message protocol themselves.
|
|
281
|
+
|
|
282
|
+
### Exported types
|
|
283
|
+
|
|
284
|
+
`Message`, `Appearance`, `ThemeVariable`, `CreateCustomerInput`, `CreatePaymentIntentInput`, `CreateSetupIntentInput`, `PaymentIntent`, `SetupIntent`, `EmbedToken`, `EmbedTokenJwt`, `RenderTokenJwt`, plus the per-form `*Options` and `*Controller` types.
|
|
285
|
+
|
|
286
|
+
## Notes and potential gotchas
|
|
287
|
+
|
|
288
|
+
- **`iframe` argument**: every messaging helper (`validateForm`, `confirmPaymentIntent`, `confirmSetupIntent`) accepts the `iframe` element directly. With the mount helpers, use `controller.iframe`.
|
|
289
|
+
- **Same components for payment vs setup intents**: `mountAmosCreditCardPaymentMethodForm` and `mountAmosBankAccountPaymentMethodForm` support both payment intents and setup intents. The flow differs only by which server call you make and which confirmation function you use. You may optionally provide `onPaymentIntentConfirmationSucceeded` and/or `onSetupIntentConfirmationSucceeded`; the appropriate one is invoked based on the flow.
|
|
290
|
+
- **Amount format**: for `mountAmosGooglePayButton`, `amount` is a string (e.g. `"5000"` for $50.00). For `CreatePaymentIntentInput` on the server, `amount` is a number in cents (e.g. `5000`).
|
|
291
|
+
- **Browser-only**: the mount and messaging helpers require `window` and the DOM. They are not safe to call during server-side rendering — call them from client-side code only (for example, inside a `useEffect`-like hook in your framework of choice).
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
295
|
+
**Full product docs:** [docs.amos.com](https://docs.amos.com)
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var R=Object.defineProperty;var o=(e,n)=>R(e,"name",{value:n,configurable:!0});Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function m(e){const[n="",t="",i=""]=e?.split(".")??[],r=typeof atob=="function"?atob:a=>Buffer.from(a,"base64").toString("utf8");return{header:JSON.parse(r(n)),payload:JSON.parse(r(t)),signature:i}}o(m,"decodeJwt");function u(e){const{env:n="sandbox"}=m(e).payload;switch(n){case"production":return"https://embed.amos.com";case"sandbox":return"https://embed-sandbox.amos.com";default:return"https://embed-sandbox.amos.com"}}o(u,"getEmbedOrigin");function F(e){return e}o(F,"createMessage");function l(e){e?.contentWindow?.postMessage({type:"PARENT_ACKNOWLEDGED_IFRAME_READY"},"*")}o(l,"sendParentReadyMessage");function c({iframe:e,appearance:n={}}){e?.contentWindow?.postMessage({type:"UPDATE_APPEARANCE",appearance:n},"*")}o(c,"updateAppearance");function y({iframe:e,amount:n}){e?.contentWindow?.postMessage({type:"UPDATE_AMOUNT",amount:n},"*")}o(y,"updateAmount");function E({iframe:e,merchantName:n}){e?.contentWindow?.postMessage({type:"UPDATE_MERCHANT_NAME",merchantName:n},"*")}o(E,"updateMerchantName");function S({iframe:e}){const n=crypto.randomUUID();return new Promise(t=>{e?.contentWindow?.postMessage({type:"VALIDATE_FORM",requestId:n},"*");const i=setTimeout(()=>{window.removeEventListener("message",r),t(!1)},5e3);function r(a){a.data.type==="VALIDATE_FORM"&&a.data.requestId===n&&(window.removeEventListener("message",r),clearTimeout(i),t(a.data.isValid??!1))}o(r,"handleMessage"),window.addEventListener("message",r)})}o(S,"validateForm");function f({iframe:e,token:n}){const{payment_intent_id:t}=m(n).payload;e?.contentWindow?.postMessage({type:"CONFIRM_PAYMENT_INTENT",token:n,id:t??void 0},"*")}o(f,"confirmPaymentIntent");function O({iframe:e,token:n}){const{setup_intent_id:t}=m(n).payload;e?.contentWindow?.postMessage({type:"CONFIRM_SETUP_INTENT",token:n,id:t??void 0},"*")}o(O,"confirmSetupIntent");function C({iframe:e,errorMessage:n}){e?.contentWindow?.postMessage({type:"CONFIRMATION_FAILED",errorMessage:n},"*")}o(C,"sendConfirmationFailed");function I(e){return`${u(e)}/iframe/google-pay?token=${e}`}o(I,"getGooglePayButtonSrc");function M(){return"40px"}o(M,"getGooglePayButtonInitialHeight");function N(e,n){let t={...n};function i(){y({iframe:e,amount:t.amount})}o(i,"pushAmount");function r(){E({iframe:e,merchantName:t.merchantName})}o(r,"pushMerchantName");function a(s){switch(s.data.type){case"IFRAME_READY":l(e),c({iframe:e,appearance:t.appearance}),i(),r();break;case"UPDATE_HEIGHT":t.onHeightChange?.(s.data.height);break;case"UPDATE_APPEARANCE":c({iframe:e,appearance:s.data.appearance});break;case"UPDATED_APPEARANCE":t.onAppearanceReady?.();break;case"CREATE_PAYMENT_INTENT":t.onInitiatePaymentIntentRequest({paymentIntentCreateAttributes:s.data.paymentIntentCreateAttributes,customerCreateAttributes:s.data.customerCreateAttributes}).then(d=>{f({iframe:e,token:d})}).catch(d=>{C({iframe:e,errorMessage:d instanceof Error?d.message:"Unknown error"})});break;case"PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":t.onPaymentIntentConfirmationSucceeded(s.data.paymentIntent);break;case"CONFIRMATION_FAILED":t.onConfirmationFailed(s.data.errorMessage);break}}return o(a,"handleMessage"),window.addEventListener("message",a),{update(s){const d="appearance"in s,p="amount"in s,w="merchantName"in s;t={...t,...s},d&&c({iframe:e,appearance:t.appearance}),p&&i(),w&&r()},destroy(){window.removeEventListener("message",a)}}}o(N,"attachGooglePayButtonListeners");function k({paymentData:e}){return{paymentMethod:{billing_address_attributes:{name:e.shippingAddress?.name,address_line1:e.shippingAddress?.address1,address_line2:e.shippingAddress?.address2,city:e.shippingAddress?.locality,state:e.shippingAddress?.administrativeArea,postal_code:e.shippingAddress?.postalCode,country:e.shippingAddress?.countryCode,email:e.email,phone:e.shippingAddress?.phoneNumber},card_profile_attributes:{wallet_provider:"googlepay",wallet_payload:e.paymentMethodData.tokenizationData.token,wallet_last4:e.paymentMethodData.info?.cardDetails,wallet_brand:(()=>{switch(e.paymentMethodData.info?.cardNetwork){case"AMEX":return"american_express";case"VISA":return"visa";case"MASTERCARD":return"master";case"DISCOVER":return"discover";default:return}})()}}}}o(k,"formatGooglePayPaymentData");function P(e,n={cardholderName:!1}){const t=Object.entries(n).filter(([,i])=>i).map(([i])=>i).join(",");return`${u(e)}/iframe/card?token=${e}&additionalFields=${t}`}o(P,"getCreditCardFormSrc");function _(e){return`${u(e)}/iframe/bank?token=${e}`}o(_,"getBankAccountFormSrc");function b(e={cardholderName:!1}){return e.cardholderName?"292px":"212px"}o(b,"getCreditCardFormInitialHeight");function T(){return"400px"}o(T,"getBankAccountFormInitialHeight");function g(e,n){let t={...n};function i(r){switch(r.data.type){case"IFRAME_READY":l(e),c({iframe:e,appearance:t.appearance});break;case"UPDATE_HEIGHT":t.onHeightChange?.(r.data.height);break;case"UPDATE_APPEARANCE":c({iframe:e,appearance:r.data.appearance});break;case"UPDATED_APPEARANCE":t.onAppearanceReady?.();break;case"PAYMENT_INTENT_CONFIRMATION_SUCCEEDED":t.onPaymentIntentConfirmationSucceeded?.(r.data.paymentIntent);break;case"SETUP_INTENT_CONFIRMATION_SUCCEEDED":t.onSetupIntentConfirmationSucceeded?.(r.data.setupIntent);break;case"CONFIRMATION_FAILED":t.onConfirmationFailed(r.data.errorMessage);break}}return o(i,"handleMessage"),window.addEventListener("message",i),{update(r){const a="appearance"in r;t={...t,...r},a&&c({iframe:e,appearance:t.appearance})},destroy(){window.removeEventListener("message",i)}}}o(g,"attachPaymentMethodFormListeners");function A(e){if(typeof e=="string"){const n=document.querySelector(e);if(!(n instanceof HTMLElement))throw new Error(`[amos-js] Container "${e}" did not match any HTMLElement.`);return n}return e}o(A,"resolveContainer");const D={width:"calc(100% + 8px)",transition:"opacity 150ms ease-in, height 200ms ease-in-out",margin:"0 -4px",opacity:"0",border:"0"};function h({src:e,title:n,name:t,height:i,allow:r}){const a=document.createElement("iframe");return a.src=e,a.title=n,a.name=t,a.setAttribute("role","presentation"),a.scrolling="no",r&&(a.allow=r),Object.assign(a.style,D,{height:i}),a}o(h,"createIframe");function H(e,n){const t=A(e),{renderToken:i,additionalFields:r={cardholderName:!1},...a}=n,s=h({src:P(i,r),title:"Secure credit card payment method form powered by Amos",name:"amos-credit-card-payment-method-form",height:b(r)});t.appendChild(s);const d=g(s,{...a,onHeightChange:o(p=>{s.style.height=p,a.onHeightChange?.(p)},"onHeightChange"),onAppearanceReady:o(()=>{s.style.opacity="1",a.onAppearanceReady?.()},"onAppearanceReady")});return{iframe:s,update:d.update,destroy(){d.destroy(),s.remove()}}}o(H,"mountAmosCreditCardPaymentMethodForm");function L(e,n){const t=A(e),{renderToken:i,...r}=n,a=h({src:_(i),title:"Secure bank account payment method form powered by Amos",name:"amos-bank-account-payment-method-form",height:T()});t.appendChild(a);const s=g(a,{...r,onHeightChange:o(d=>{a.style.height=d,r.onHeightChange?.(d)},"onHeightChange"),onAppearanceReady:o(()=>{a.style.opacity="1",r.onAppearanceReady?.()},"onAppearanceReady")});return{iframe:a,update:s.update,destroy(){s.destroy(),a.remove()}}}o(L,"mountAmosBankAccountPaymentMethodForm");function U(e,n){const t=A(e),{renderToken:i,...r}=n,a=h({src:I(i),title:"Secure Google Pay button powered by Amos",name:"amos-google-pay-button",height:M(),allow:"payment"});t.appendChild(a);const s=N(a,{...r,onHeightChange:o(d=>{a.style.height=d,r.onHeightChange?.(d)},"onHeightChange"),onAppearanceReady:o(()=>{a.style.opacity="1",r.onAppearanceReady?.()},"onAppearanceReady")});return{iframe:a,update:s.update,destroy(){s.destroy(),a.remove()}}}o(U,"mountAmosGooglePayButton");exports.attachGooglePayButtonListeners=N;exports.attachPaymentMethodFormListeners=g;exports.confirmPaymentIntent=f;exports.confirmSetupIntent=O;exports.createMessage=F;exports.decodeJwt=m;exports.formatGooglePayPaymentData=k;exports.getBankAccountFormInitialHeight=T;exports.getBankAccountFormSrc=_;exports.getCreditCardFormInitialHeight=b;exports.getCreditCardFormSrc=P;exports.getEmbedOrigin=u;exports.getGooglePayButtonInitialHeight=M;exports.getGooglePayButtonSrc=I;exports.mountAmosBankAccountPaymentMethodForm=L;exports.mountAmosCreditCardPaymentMethodForm=H;exports.mountAmosGooglePayButton=U;exports.sendConfirmationFailed=C;exports.sendParentReadyMessage=l;exports.updateAmount=y;exports.updateAppearance=c;exports.updateMerchantName=E;exports.validateForm=S;
|