@amos.com/amos-js 0.9.9 → 0.9.11
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 +36 -4
- package/dist/apple-pay.d.ts +5 -3
- package/dist/google-pay.d.ts +6 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +154 -98
- package/dist/messaging.d.ts +15 -1
- package/dist/payment-method-form.d.ts +7 -1
- package/dist/types.d.ts +121 -0
- package/package.json +1 -1
- package/src/apple-pay.ts +19 -2
- package/src/google-pay.ts +28 -3
- package/src/index.ts +14 -1
- package/src/messaging.ts +55 -1
- package/src/payment-method-form.ts +16 -1
- package/src/types.ts +221 -0
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { components } from '@amos.com/node';
|
|
2
|
+
/**
|
|
3
|
+
* PCI-safe snapshot of card/bank form validity, posted when HTML
|
|
4
|
+
* constraint validation changes. Use this to enable or disable a host
|
|
5
|
+
* checkout button.
|
|
6
|
+
*/
|
|
7
|
+
export type PaymentMethodFormValidityChangeEvent = {
|
|
8
|
+
isValid: boolean;
|
|
9
|
+
};
|
|
2
10
|
/**
|
|
3
11
|
* Why an interactive confirmation attempt ended with `status: "incomplete"`.
|
|
4
12
|
*
|
|
@@ -69,6 +77,99 @@ export type Appearance = {
|
|
|
69
77
|
*/
|
|
70
78
|
labels?: AppearanceLabels;
|
|
71
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* Inline style bag sent through `postMessage` to the wallet-button iframe.
|
|
82
|
+
*
|
|
83
|
+
* Matches the serializable subset of a CSSStyleDeclaration / React
|
|
84
|
+
* `CSSProperties` object (string or number values). Custom properties such
|
|
85
|
+
* as `--apple-pay-button-height` are allowed.
|
|
86
|
+
*/
|
|
87
|
+
export type WalletButtonStyle = {
|
|
88
|
+
[property: string]: string | number | undefined;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* `buttonstyle` attribute on Apple's `<apple-pay-button>`.
|
|
92
|
+
*
|
|
93
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
94
|
+
*/
|
|
95
|
+
export type ApplePayButtonStyle = "black" | "white" | "white-outline";
|
|
96
|
+
/**
|
|
97
|
+
* `type` attribute on Apple's `<apple-pay-button>`.
|
|
98
|
+
*
|
|
99
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
100
|
+
*/
|
|
101
|
+
export type ApplePayButtonType = "plain" | "buy" | "set-up" | "donate" | "check-out" | "book" | "subscribe" | "reload" | "add-money" | "top-up" | "order" | "rent" | "support" | "contribute" | "tip";
|
|
102
|
+
/**
|
|
103
|
+
* Visual props for Apple's `<apple-pay-button>`, using Apple's attribute
|
|
104
|
+
* names. Applied inside the Amos embed iframe.
|
|
105
|
+
*
|
|
106
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
107
|
+
*/
|
|
108
|
+
export type ApplePayButtonElementProps = {
|
|
109
|
+
/**
|
|
110
|
+
* Apple Pay button color.
|
|
111
|
+
*
|
|
112
|
+
* @default "black"
|
|
113
|
+
*/
|
|
114
|
+
buttonstyle?: ApplePayButtonStyle;
|
|
115
|
+
/**
|
|
116
|
+
* Apple Pay button label / verb.
|
|
117
|
+
*
|
|
118
|
+
* @default "plain"
|
|
119
|
+
*/
|
|
120
|
+
type?: ApplePayButtonType;
|
|
121
|
+
/**
|
|
122
|
+
* BCP 47 locale for the button label (e.g. `"en-US"`).
|
|
123
|
+
*
|
|
124
|
+
* @default "en-US"
|
|
125
|
+
*/
|
|
126
|
+
locale?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Inline style for the `<apple-pay-button>`. Height is controlled with
|
|
129
|
+
* `--apple-pay-button-height` (Apple ignores CSS `height`). Width uses
|
|
130
|
+
* `--apple-pay-button-width` or CSS `width`.
|
|
131
|
+
*/
|
|
132
|
+
style?: WalletButtonStyle;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Visual props for Google's Pay button, using `@google-pay/button-react`
|
|
136
|
+
* / Google Pay API names. Applied inside the Amos embed iframe.
|
|
137
|
+
*
|
|
138
|
+
* @see https://developers.google.com/pay/api/web/guides/resources/customize
|
|
139
|
+
*/
|
|
140
|
+
export type GooglePayButtonElementProps = {
|
|
141
|
+
/**
|
|
142
|
+
* Button label / verb.
|
|
143
|
+
*
|
|
144
|
+
* @default "short"
|
|
145
|
+
*/
|
|
146
|
+
buttonType?: google.payments.api.ButtonType;
|
|
147
|
+
/** Button color. */
|
|
148
|
+
buttonColor?: google.payments.api.ButtonColor;
|
|
149
|
+
/** Corner radius in pixels (0–20). */
|
|
150
|
+
buttonRadius?: number;
|
|
151
|
+
/**
|
|
152
|
+
* `"fill"` stretches the button to the container width; `"static"`
|
|
153
|
+
* uses Google's default size.
|
|
154
|
+
*/
|
|
155
|
+
buttonSizeMode?: google.payments.api.ButtonSizeMode;
|
|
156
|
+
/** BCP 47 locale for the button label (e.g. `"en"`). */
|
|
157
|
+
buttonLocale?: string;
|
|
158
|
+
/** Whether the button draws a border. */
|
|
159
|
+
buttonBorderType?: google.payments.api.ButtonBorderType;
|
|
160
|
+
/**
|
|
161
|
+
* Inline style for the Google Pay button wrapper. Use `height` /
|
|
162
|
+
* `width` here (unlike Apple Pay, Google honors CSS `height`).
|
|
163
|
+
*/
|
|
164
|
+
style?: WalletButtonStyle;
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Keep only JSON-cloneable string/number declarations from a style object
|
|
168
|
+
* before sending it through `postMessage`.
|
|
169
|
+
*/
|
|
170
|
+
export declare function serializeWalletButtonStyle(style: WalletButtonStyle | undefined): Record<string, string | number> | undefined;
|
|
171
|
+
export declare function pickApplePayButtonElementProps(options: ApplePayButtonElementProps): ApplePayButtonElementProps;
|
|
172
|
+
export declare function pickGooglePayButtonElementProps(options: GooglePayButtonElementProps): GooglePayButtonElementProps;
|
|
72
173
|
/**
|
|
73
174
|
* Typed `postMessage` payloads exchanged between the host page and the
|
|
74
175
|
* embedded Amos iframe.
|
|
@@ -95,6 +196,18 @@ export type Message = {
|
|
|
95
196
|
/** Parent → embed: push appearance overrides into the iframe. */
|
|
96
197
|
type: "UPDATE_APPEARANCE";
|
|
97
198
|
appearance: Appearance;
|
|
199
|
+
} | {
|
|
200
|
+
/**
|
|
201
|
+
* Parent → embed: visual options for the Apple Pay button. Nested
|
|
202
|
+
* under `props` so Apple's `type` attribute does not collide with
|
|
203
|
+
* this message discriminant.
|
|
204
|
+
*/
|
|
205
|
+
type: "UPDATE_APPLE_PAY_BUTTON";
|
|
206
|
+
props: ApplePayButtonElementProps;
|
|
207
|
+
} | {
|
|
208
|
+
/** Parent → embed: visual options for the Google Pay button. */
|
|
209
|
+
type: "UPDATE_GOOGLE_PAY_BUTTON";
|
|
210
|
+
props: GooglePayButtonElementProps;
|
|
98
211
|
} | {
|
|
99
212
|
/**
|
|
100
213
|
* Parent → embed: validate form inputs (`requestId` only).
|
|
@@ -138,6 +251,14 @@ export type Message = {
|
|
|
138
251
|
} | {
|
|
139
252
|
/** Parent → embed: clear all form field values and API errors. */
|
|
140
253
|
type: "RESET_FORM";
|
|
254
|
+
} | {
|
|
255
|
+
/**
|
|
256
|
+
* Embed → parent: card/bank form validity changed.
|
|
257
|
+
* `isValid` is true when all required fields are present and
|
|
258
|
+
* valid. Does not include PCI data.
|
|
259
|
+
*/
|
|
260
|
+
type: "FORM_VALIDITY_CHANGE";
|
|
261
|
+
isValid: boolean;
|
|
141
262
|
};
|
|
142
263
|
/**
|
|
143
264
|
* Identity helper that brands an object as a typed `Message`.
|
package/package.json
CHANGED
package/src/apple-pay.ts
CHANGED
|
@@ -10,10 +10,12 @@ import {
|
|
|
10
10
|
sendParentReadyMessage,
|
|
11
11
|
updateAmount as sendUpdateAmount,
|
|
12
12
|
updateAppearance as sendUpdateAppearance,
|
|
13
|
+
updateApplePayButton as sendUpdateApplePayButton,
|
|
13
14
|
updateMerchantName as sendUpdateMerchantName,
|
|
14
15
|
} from "./messaging";
|
|
15
16
|
import {
|
|
16
17
|
type Appearance,
|
|
18
|
+
type ApplePayButtonElementProps,
|
|
17
19
|
type ConfirmationResult,
|
|
18
20
|
createMessage,
|
|
19
21
|
type Message,
|
|
@@ -36,7 +38,7 @@ export function getApplePayButtonInitialHeight(): string {
|
|
|
36
38
|
/**
|
|
37
39
|
* Options accepted by {@link attachApplePayButtonListeners}.
|
|
38
40
|
*/
|
|
39
|
-
export type ApplePayButtonListenerOptions = {
|
|
41
|
+
export type ApplePayButtonListenerOptions = ApplePayButtonElementProps & {
|
|
40
42
|
/** The amount of the payment, in the same format passed in props. */
|
|
41
43
|
amount: string;
|
|
42
44
|
/** A user-visible merchant name. */
|
|
@@ -83,7 +85,9 @@ export type ApplePayButtonController = {
|
|
|
83
85
|
/**
|
|
84
86
|
* Update one or more listener options without re-attaching the
|
|
85
87
|
* message listener. Pass `amount` or `merchantName` to push the new
|
|
86
|
-
* value into the iframe; pass `appearance` to update theme variables
|
|
88
|
+
* value into the iframe; pass `appearance` to update theme variables;
|
|
89
|
+
* pass `buttonstyle`, `type`, `locale`, or `style` to restyle the
|
|
90
|
+
* Apple Pay button.
|
|
87
91
|
*/
|
|
88
92
|
update: (patch: Partial<ApplePayButtonListenerOptions>) => void;
|
|
89
93
|
/**
|
|
@@ -126,6 +130,10 @@ export function attachApplePayButtonListeners(
|
|
|
126
130
|
sendUpdateMerchantName({ iframe, merchantName: current.merchantName });
|
|
127
131
|
}
|
|
128
132
|
|
|
133
|
+
function pushButtonProps() {
|
|
134
|
+
sendUpdateApplePayButton({ iframe, props: current });
|
|
135
|
+
}
|
|
136
|
+
|
|
129
137
|
function handleMessage(event: MessageEvent<Message>) {
|
|
130
138
|
// Ignore messages from other frames / windows.
|
|
131
139
|
if (event.source !== iframe.contentWindow) {
|
|
@@ -138,6 +146,7 @@ export function attachApplePayButtonListeners(
|
|
|
138
146
|
sendUpdateAppearance({ iframe, appearance: current.appearance });
|
|
139
147
|
pushAmount();
|
|
140
148
|
pushMerchantName();
|
|
149
|
+
pushButtonProps();
|
|
141
150
|
break;
|
|
142
151
|
|
|
143
152
|
case "UPDATE_HEIGHT":
|
|
@@ -199,6 +208,11 @@ export function attachApplePayButtonListeners(
|
|
|
199
208
|
const hadAppearance = "appearance" in patch;
|
|
200
209
|
const hadAmount = "amount" in patch;
|
|
201
210
|
const hadMerchantName = "merchantName" in patch;
|
|
211
|
+
const hadButtonProps =
|
|
212
|
+
"buttonstyle" in patch ||
|
|
213
|
+
"type" in patch ||
|
|
214
|
+
"locale" in patch ||
|
|
215
|
+
"style" in patch;
|
|
202
216
|
current = { ...current, ...patch };
|
|
203
217
|
if (hadAppearance) {
|
|
204
218
|
sendUpdateAppearance({ iframe, appearance: current.appearance });
|
|
@@ -209,6 +223,9 @@ export function attachApplePayButtonListeners(
|
|
|
209
223
|
if (hadMerchantName) {
|
|
210
224
|
pushMerchantName();
|
|
211
225
|
}
|
|
226
|
+
if (hadButtonProps) {
|
|
227
|
+
pushButtonProps();
|
|
228
|
+
}
|
|
212
229
|
},
|
|
213
230
|
destroy() {
|
|
214
231
|
window.removeEventListener("message", handleMessage);
|
package/src/google-pay.ts
CHANGED
|
@@ -7,9 +7,15 @@ import {
|
|
|
7
7
|
sendParentReadyMessage,
|
|
8
8
|
updateAmount as sendUpdateAmount,
|
|
9
9
|
updateAppearance as sendUpdateAppearance,
|
|
10
|
+
updateGooglePayButton as sendUpdateGooglePayButton,
|
|
10
11
|
updateMerchantName as sendUpdateMerchantName,
|
|
11
12
|
} from "./messaging";
|
|
12
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
Appearance,
|
|
15
|
+
ConfirmationResult,
|
|
16
|
+
GooglePayButtonElementProps,
|
|
17
|
+
Message,
|
|
18
|
+
} from "./types";
|
|
13
19
|
|
|
14
20
|
/**
|
|
15
21
|
* Build the iframe `src` URL for the embedded Google Pay button.
|
|
@@ -28,7 +34,7 @@ export function getGooglePayButtonInitialHeight(): string {
|
|
|
28
34
|
/**
|
|
29
35
|
* Options accepted by {@link attachGooglePayButtonListeners}.
|
|
30
36
|
*/
|
|
31
|
-
export type GooglePayButtonListenerOptions = {
|
|
37
|
+
export type GooglePayButtonListenerOptions = GooglePayButtonElementProps & {
|
|
32
38
|
/** The amount of the payment, in the same format passed in props. */
|
|
33
39
|
amount: string;
|
|
34
40
|
/** A user-visible merchant name. */
|
|
@@ -75,7 +81,10 @@ export type GooglePayButtonController = {
|
|
|
75
81
|
/**
|
|
76
82
|
* Update one or more listener options without re-attaching the
|
|
77
83
|
* message listener. Pass `amount` or `merchantName` to push the new
|
|
78
|
-
* value into the iframe; pass `appearance` to update theme variables
|
|
84
|
+
* value into the iframe; pass `appearance` to update theme variables;
|
|
85
|
+
* pass `buttonType`, `buttonColor`, `buttonRadius`, `buttonSizeMode`,
|
|
86
|
+
* `buttonLocale`, `buttonBorderType`, or `style` to restyle the
|
|
87
|
+
* Google Pay button.
|
|
79
88
|
*/
|
|
80
89
|
update: (patch: Partial<GooglePayButtonListenerOptions>) => void;
|
|
81
90
|
/**
|
|
@@ -106,6 +115,10 @@ export function attachGooglePayButtonListeners(
|
|
|
106
115
|
sendUpdateMerchantName({ iframe, merchantName: current.merchantName });
|
|
107
116
|
}
|
|
108
117
|
|
|
118
|
+
function pushButtonProps() {
|
|
119
|
+
sendUpdateGooglePayButton({ iframe, props: current });
|
|
120
|
+
}
|
|
121
|
+
|
|
109
122
|
function handleMessage(event: MessageEvent<Message>) {
|
|
110
123
|
if (event.source !== iframe.contentWindow) {
|
|
111
124
|
return;
|
|
@@ -117,6 +130,7 @@ export function attachGooglePayButtonListeners(
|
|
|
117
130
|
sendUpdateAppearance({ iframe, appearance: current.appearance });
|
|
118
131
|
pushAmount();
|
|
119
132
|
pushMerchantName();
|
|
133
|
+
pushButtonProps();
|
|
120
134
|
break;
|
|
121
135
|
|
|
122
136
|
case "UPDATE_HEIGHT":
|
|
@@ -163,6 +177,14 @@ export function attachGooglePayButtonListeners(
|
|
|
163
177
|
const hadAppearance = "appearance" in patch;
|
|
164
178
|
const hadAmount = "amount" in patch;
|
|
165
179
|
const hadMerchantName = "merchantName" in patch;
|
|
180
|
+
const hadButtonProps =
|
|
181
|
+
"buttonType" in patch ||
|
|
182
|
+
"buttonColor" in patch ||
|
|
183
|
+
"buttonRadius" in patch ||
|
|
184
|
+
"buttonSizeMode" in patch ||
|
|
185
|
+
"buttonLocale" in patch ||
|
|
186
|
+
"buttonBorderType" in patch ||
|
|
187
|
+
"style" in patch;
|
|
166
188
|
current = { ...current, ...patch };
|
|
167
189
|
if (hadAppearance) {
|
|
168
190
|
sendUpdateAppearance({ iframe, appearance: current.appearance });
|
|
@@ -173,6 +195,9 @@ export function attachGooglePayButtonListeners(
|
|
|
173
195
|
if (hadMerchantName) {
|
|
174
196
|
pushMerchantName();
|
|
175
197
|
}
|
|
198
|
+
if (hadButtonProps) {
|
|
199
|
+
pushButtonProps();
|
|
200
|
+
}
|
|
176
201
|
},
|
|
177
202
|
destroy() {
|
|
178
203
|
window.removeEventListener("message", handleMessage);
|
package/src/index.ts
CHANGED
|
@@ -32,6 +32,8 @@ export {
|
|
|
32
32
|
sendParentReadyMessage,
|
|
33
33
|
updateAmount,
|
|
34
34
|
updateAppearance,
|
|
35
|
+
updateApplePayButton,
|
|
36
|
+
updateGooglePayButton,
|
|
35
37
|
updateMerchantName,
|
|
36
38
|
validateForm,
|
|
37
39
|
} from "./messaging";
|
|
@@ -66,9 +68,20 @@ export {
|
|
|
66
68
|
export type {
|
|
67
69
|
Appearance,
|
|
68
70
|
AppearanceLabels,
|
|
71
|
+
ApplePayButtonElementProps,
|
|
72
|
+
ApplePayButtonStyle,
|
|
73
|
+
ApplePayButtonType,
|
|
69
74
|
ConfirmationIncompleteReason,
|
|
70
75
|
ConfirmationResult,
|
|
76
|
+
GooglePayButtonElementProps,
|
|
71
77
|
Message,
|
|
78
|
+
PaymentMethodFormValidityChangeEvent,
|
|
72
79
|
ThemeVariable,
|
|
80
|
+
WalletButtonStyle,
|
|
81
|
+
} from "./types";
|
|
82
|
+
export {
|
|
83
|
+
createMessage,
|
|
84
|
+
pickApplePayButtonElementProps,
|
|
85
|
+
pickGooglePayButtonElementProps,
|
|
86
|
+
serializeWalletButtonStyle,
|
|
73
87
|
} from "./types";
|
|
74
|
-
export { createMessage } from "./types";
|
package/src/messaging.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import type { components } from "@amos.com/node";
|
|
2
2
|
import { decodeJwt } from "./jwt";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type Appearance,
|
|
5
|
+
type ApplePayButtonElementProps,
|
|
6
|
+
createMessage,
|
|
7
|
+
type GooglePayButtonElementProps,
|
|
8
|
+
type Message,
|
|
9
|
+
pickApplePayButtonElementProps,
|
|
10
|
+
pickGooglePayButtonElementProps,
|
|
11
|
+
} from "./types";
|
|
4
12
|
|
|
5
13
|
type Iframe = HTMLIFrameElement | null | undefined;
|
|
6
14
|
|
|
@@ -55,6 +63,52 @@ export function updateAppearance({
|
|
|
55
63
|
);
|
|
56
64
|
}
|
|
57
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Push Apple Pay button visual options into the embedded iframe.
|
|
68
|
+
*/
|
|
69
|
+
export function updateApplePayButton({
|
|
70
|
+
iframe,
|
|
71
|
+
props,
|
|
72
|
+
}: {
|
|
73
|
+
iframe: Iframe;
|
|
74
|
+
props: ApplePayButtonElementProps;
|
|
75
|
+
}): void {
|
|
76
|
+
if (!iframe?.contentWindow) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
iframe.contentWindow.postMessage(
|
|
81
|
+
createMessage({
|
|
82
|
+
type: "UPDATE_APPLE_PAY_BUTTON",
|
|
83
|
+
props: pickApplePayButtonElementProps(props),
|
|
84
|
+
}),
|
|
85
|
+
getIframeTargetOrigin(iframe),
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Push Google Pay button visual options into the embedded iframe.
|
|
91
|
+
*/
|
|
92
|
+
export function updateGooglePayButton({
|
|
93
|
+
iframe,
|
|
94
|
+
props,
|
|
95
|
+
}: {
|
|
96
|
+
iframe: Iframe;
|
|
97
|
+
props: GooglePayButtonElementProps;
|
|
98
|
+
}): void {
|
|
99
|
+
if (!iframe?.contentWindow) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
iframe.contentWindow.postMessage(
|
|
104
|
+
createMessage({
|
|
105
|
+
type: "UPDATE_GOOGLE_PAY_BUTTON",
|
|
106
|
+
props: pickGooglePayButtonElementProps(props),
|
|
107
|
+
}),
|
|
108
|
+
getIframeTargetOrigin(iframe),
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
58
112
|
/**
|
|
59
113
|
* Push the express-checkout amount into the embedded Google Pay iframe.
|
|
60
114
|
*/
|
|
@@ -3,7 +3,12 @@ import {
|
|
|
3
3
|
sendParentReadyMessage,
|
|
4
4
|
updateAppearance as sendUpdateAppearance,
|
|
5
5
|
} from "./messaging";
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
Appearance,
|
|
8
|
+
ConfirmationResult,
|
|
9
|
+
Message,
|
|
10
|
+
PaymentMethodFormValidityChangeEvent,
|
|
11
|
+
} from "./types";
|
|
7
12
|
|
|
8
13
|
/**
|
|
9
14
|
* The additional fields beyond the standard card number, expiration
|
|
@@ -126,6 +131,12 @@ export type PaymentMethodFormListenerOptions = {
|
|
|
126
131
|
* iframe's opacity from `0` to `1` to fade it in.
|
|
127
132
|
*/
|
|
128
133
|
onAppearanceReady?: () => void;
|
|
134
|
+
/**
|
|
135
|
+
* Called when card/bank form validity changes. `isValid` is true
|
|
136
|
+
* when all required fields are present and valid. Does not include
|
|
137
|
+
* PCI data. Use this to enable or disable a host checkout button.
|
|
138
|
+
*/
|
|
139
|
+
onValidityChange?: (event: PaymentMethodFormValidityChangeEvent) => void;
|
|
129
140
|
/**
|
|
130
141
|
* Called when the interactive confirmation flow finishes (success or
|
|
131
142
|
* terminal failure). Not settlement proof — verify via webhooks.
|
|
@@ -191,6 +202,10 @@ export function attachPaymentMethodFormListeners(
|
|
|
191
202
|
current.onAppearanceReady?.();
|
|
192
203
|
break;
|
|
193
204
|
|
|
205
|
+
case "FORM_VALIDITY_CHANGE":
|
|
206
|
+
current.onValidityChange?.({ isValid: event.data.isValid });
|
|
207
|
+
break;
|
|
208
|
+
|
|
194
209
|
case "CONFIRMATION_RESULT":
|
|
195
210
|
current.onResult(event.data.result);
|
|
196
211
|
break;
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
|
+
/// <reference types="googlepay" />
|
|
2
|
+
|
|
1
3
|
import type { components } from "@amos.com/node";
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* PCI-safe snapshot of card/bank form validity, posted when HTML
|
|
7
|
+
* constraint validation changes. Use this to enable or disable a host
|
|
8
|
+
* checkout button.
|
|
9
|
+
*/
|
|
10
|
+
export type PaymentMethodFormValidityChangeEvent = {
|
|
11
|
+
isValid: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
3
14
|
/**
|
|
4
15
|
* Why an interactive confirmation attempt ended with `status: "incomplete"`.
|
|
5
16
|
*
|
|
@@ -303,6 +314,193 @@ export type Appearance = {
|
|
|
303
314
|
labels?: AppearanceLabels;
|
|
304
315
|
};
|
|
305
316
|
|
|
317
|
+
/**
|
|
318
|
+
* Inline style bag sent through `postMessage` to the wallet-button iframe.
|
|
319
|
+
*
|
|
320
|
+
* Matches the serializable subset of a CSSStyleDeclaration / React
|
|
321
|
+
* `CSSProperties` object (string or number values). Custom properties such
|
|
322
|
+
* as `--apple-pay-button-height` are allowed.
|
|
323
|
+
*/
|
|
324
|
+
export type WalletButtonStyle = {
|
|
325
|
+
[property: string]: string | number | undefined;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* `buttonstyle` attribute on Apple's `<apple-pay-button>`.
|
|
330
|
+
*
|
|
331
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
332
|
+
*/
|
|
333
|
+
export type ApplePayButtonStyle = "black" | "white" | "white-outline";
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* `type` attribute on Apple's `<apple-pay-button>`.
|
|
337
|
+
*
|
|
338
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
339
|
+
*/
|
|
340
|
+
export type ApplePayButtonType =
|
|
341
|
+
| "plain"
|
|
342
|
+
| "buy"
|
|
343
|
+
| "set-up"
|
|
344
|
+
| "donate"
|
|
345
|
+
| "check-out"
|
|
346
|
+
| "book"
|
|
347
|
+
| "subscribe"
|
|
348
|
+
| "reload"
|
|
349
|
+
| "add-money"
|
|
350
|
+
| "top-up"
|
|
351
|
+
| "order"
|
|
352
|
+
| "rent"
|
|
353
|
+
| "support"
|
|
354
|
+
| "contribute"
|
|
355
|
+
| "tip";
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Visual props for Apple's `<apple-pay-button>`, using Apple's attribute
|
|
359
|
+
* names. Applied inside the Amos embed iframe.
|
|
360
|
+
*
|
|
361
|
+
* @see https://developer.apple.com/documentation/apple_pay_on_the_web/apple-pay-button
|
|
362
|
+
*/
|
|
363
|
+
export type ApplePayButtonElementProps = {
|
|
364
|
+
/**
|
|
365
|
+
* Apple Pay button color.
|
|
366
|
+
*
|
|
367
|
+
* @default "black"
|
|
368
|
+
*/
|
|
369
|
+
buttonstyle?: ApplePayButtonStyle;
|
|
370
|
+
/**
|
|
371
|
+
* Apple Pay button label / verb.
|
|
372
|
+
*
|
|
373
|
+
* @default "plain"
|
|
374
|
+
*/
|
|
375
|
+
type?: ApplePayButtonType;
|
|
376
|
+
/**
|
|
377
|
+
* BCP 47 locale for the button label (e.g. `"en-US"`).
|
|
378
|
+
*
|
|
379
|
+
* @default "en-US"
|
|
380
|
+
*/
|
|
381
|
+
locale?: string;
|
|
382
|
+
/**
|
|
383
|
+
* Inline style for the `<apple-pay-button>`. Height is controlled with
|
|
384
|
+
* `--apple-pay-button-height` (Apple ignores CSS `height`). Width uses
|
|
385
|
+
* `--apple-pay-button-width` or CSS `width`.
|
|
386
|
+
*/
|
|
387
|
+
style?: WalletButtonStyle;
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Visual props for Google's Pay button, using `@google-pay/button-react`
|
|
392
|
+
* / Google Pay API names. Applied inside the Amos embed iframe.
|
|
393
|
+
*
|
|
394
|
+
* @see https://developers.google.com/pay/api/web/guides/resources/customize
|
|
395
|
+
*/
|
|
396
|
+
export type GooglePayButtonElementProps = {
|
|
397
|
+
/**
|
|
398
|
+
* Button label / verb.
|
|
399
|
+
*
|
|
400
|
+
* @default "short"
|
|
401
|
+
*/
|
|
402
|
+
buttonType?: google.payments.api.ButtonType;
|
|
403
|
+
/** Button color. */
|
|
404
|
+
buttonColor?: google.payments.api.ButtonColor;
|
|
405
|
+
/** Corner radius in pixels (0–20). */
|
|
406
|
+
buttonRadius?: number;
|
|
407
|
+
/**
|
|
408
|
+
* `"fill"` stretches the button to the container width; `"static"`
|
|
409
|
+
* uses Google's default size.
|
|
410
|
+
*/
|
|
411
|
+
buttonSizeMode?: google.payments.api.ButtonSizeMode;
|
|
412
|
+
/** BCP 47 locale for the button label (e.g. `"en"`). */
|
|
413
|
+
buttonLocale?: string;
|
|
414
|
+
/** Whether the button draws a border. */
|
|
415
|
+
buttonBorderType?: google.payments.api.ButtonBorderType;
|
|
416
|
+
/**
|
|
417
|
+
* Inline style for the Google Pay button wrapper. Use `height` /
|
|
418
|
+
* `width` here (unlike Apple Pay, Google honors CSS `height`).
|
|
419
|
+
*/
|
|
420
|
+
style?: WalletButtonStyle;
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* Keep only JSON-cloneable string/number declarations from a style object
|
|
425
|
+
* before sending it through `postMessage`.
|
|
426
|
+
*/
|
|
427
|
+
export function serializeWalletButtonStyle(
|
|
428
|
+
style: WalletButtonStyle | undefined,
|
|
429
|
+
): Record<string, string | number> | undefined {
|
|
430
|
+
if (!style || typeof style !== "object") {
|
|
431
|
+
return undefined;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
const result: Record<string, string | number> = {};
|
|
435
|
+
for (const [key, value] of Object.entries(style)) {
|
|
436
|
+
if (typeof value === "string") {
|
|
437
|
+
if (value.length === 0) {
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
440
|
+
result[key] = value;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
444
|
+
result[key] = value;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export function pickApplePayButtonElementProps(
|
|
452
|
+
options: ApplePayButtonElementProps,
|
|
453
|
+
): ApplePayButtonElementProps {
|
|
454
|
+
const props: ApplePayButtonElementProps = {};
|
|
455
|
+
if (options.buttonstyle !== undefined) {
|
|
456
|
+
props.buttonstyle = options.buttonstyle;
|
|
457
|
+
}
|
|
458
|
+
if (options.type !== undefined) {
|
|
459
|
+
props.type = options.type;
|
|
460
|
+
}
|
|
461
|
+
if (options.locale !== undefined) {
|
|
462
|
+
props.locale = options.locale;
|
|
463
|
+
}
|
|
464
|
+
if (options.style !== undefined) {
|
|
465
|
+
const style = serializeWalletButtonStyle(options.style);
|
|
466
|
+
if (style) {
|
|
467
|
+
props.style = style;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return props;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
export function pickGooglePayButtonElementProps(
|
|
474
|
+
options: GooglePayButtonElementProps,
|
|
475
|
+
): GooglePayButtonElementProps {
|
|
476
|
+
const props: GooglePayButtonElementProps = {};
|
|
477
|
+
if (options.buttonType !== undefined) {
|
|
478
|
+
props.buttonType = options.buttonType;
|
|
479
|
+
}
|
|
480
|
+
if (options.buttonColor !== undefined) {
|
|
481
|
+
props.buttonColor = options.buttonColor;
|
|
482
|
+
}
|
|
483
|
+
if (options.buttonRadius !== undefined) {
|
|
484
|
+
props.buttonRadius = options.buttonRadius;
|
|
485
|
+
}
|
|
486
|
+
if (options.buttonSizeMode !== undefined) {
|
|
487
|
+
props.buttonSizeMode = options.buttonSizeMode;
|
|
488
|
+
}
|
|
489
|
+
if (options.buttonLocale !== undefined) {
|
|
490
|
+
props.buttonLocale = options.buttonLocale;
|
|
491
|
+
}
|
|
492
|
+
if (options.buttonBorderType !== undefined) {
|
|
493
|
+
props.buttonBorderType = options.buttonBorderType;
|
|
494
|
+
}
|
|
495
|
+
if (options.style !== undefined) {
|
|
496
|
+
const style = serializeWalletButtonStyle(options.style);
|
|
497
|
+
if (style) {
|
|
498
|
+
props.style = style;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return props;
|
|
502
|
+
}
|
|
503
|
+
|
|
306
504
|
/**
|
|
307
505
|
* Typed `postMessage` payloads exchanged between the host page and the
|
|
308
506
|
* embedded Amos iframe.
|
|
@@ -336,6 +534,20 @@ export type Message =
|
|
|
336
534
|
type: "UPDATE_APPEARANCE";
|
|
337
535
|
appearance: Appearance;
|
|
338
536
|
}
|
|
537
|
+
| {
|
|
538
|
+
/**
|
|
539
|
+
* Parent → embed: visual options for the Apple Pay button. Nested
|
|
540
|
+
* under `props` so Apple's `type` attribute does not collide with
|
|
541
|
+
* this message discriminant.
|
|
542
|
+
*/
|
|
543
|
+
type: "UPDATE_APPLE_PAY_BUTTON";
|
|
544
|
+
props: ApplePayButtonElementProps;
|
|
545
|
+
}
|
|
546
|
+
| {
|
|
547
|
+
/** Parent → embed: visual options for the Google Pay button. */
|
|
548
|
+
type: "UPDATE_GOOGLE_PAY_BUTTON";
|
|
549
|
+
props: GooglePayButtonElementProps;
|
|
550
|
+
}
|
|
339
551
|
| {
|
|
340
552
|
/**
|
|
341
553
|
* Parent → embed: validate form inputs (`requestId` only).
|
|
@@ -390,6 +602,15 @@ export type Message =
|
|
|
390
602
|
| {
|
|
391
603
|
/** Parent → embed: clear all form field values and API errors. */
|
|
392
604
|
type: "RESET_FORM";
|
|
605
|
+
}
|
|
606
|
+
| {
|
|
607
|
+
/**
|
|
608
|
+
* Embed → parent: card/bank form validity changed.
|
|
609
|
+
* `isValid` is true when all required fields are present and
|
|
610
|
+
* valid. Does not include PCI data.
|
|
611
|
+
*/
|
|
612
|
+
type: "FORM_VALIDITY_CHANGE";
|
|
613
|
+
isValid: boolean;
|
|
393
614
|
};
|
|
394
615
|
|
|
395
616
|
/**
|