@payrails/web-sdk 5.46.1 → 5.47.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payrails/web-sdk",
3
- "version": "5.46.1",
3
+ "version": "5.47.0",
4
4
  "description": "SDK providing tokenization options on the client for merchants",
5
5
  "main": "index.js",
6
6
  "types": "payrails.d.ts",
@@ -13,8 +13,7 @@
13
13
  "@rollup/plugin-html": "2.0.0",
14
14
  "@types/applepayjs": "14.0.9",
15
15
  "@types/googlepay": "0.7.5",
16
- "rollup-plugin-import-css": "3.5.8",
17
- "vitest-fetch-mock": "0.4.5"
16
+ "rollup-plugin-import-css": "3.5.8"
18
17
  },
19
18
  "module": "index.mjs",
20
19
  "exports": {
@@ -95,6 +95,213 @@
95
95
  }
96
96
  }
97
97
 
98
+ .payrails-billing-address-form {
99
+ display: block;
100
+ margin-bottom: 16px;
101
+ }
102
+
103
+ .payrails-billing-address-form-title {
104
+ font-size: 14px;
105
+ font-weight: 600;
106
+ color: #1f2733;
107
+ margin-bottom: 12px;
108
+ }
109
+
110
+ .payrails-billing-address-form .payrails-dynamic-element-form {
111
+ display: flex;
112
+ flex-direction: row;
113
+ flex-wrap: wrap;
114
+ gap: 12px;
115
+ }
116
+
117
+ .payrails-billing-address-form .payrails-dynamic-element-form-field {
118
+ flex: 1 1 100%;
119
+ gap: 0;
120
+ }
121
+
122
+ .payrails-billing-address-form [id='payrails-dynamic-element-field:city'],
123
+ .payrails-billing-address-form [id='payrails-dynamic-element-field:state'] {
124
+ flex: 1 1 calc(50% - 6px);
125
+ }
126
+
127
+ /* Placeholder-driven design: labels stay for accessibility but are hidden. */
128
+ .payrails-billing-address-form .payrails-dynamic-element-form-field-label {
129
+ position: absolute;
130
+ width: 1px;
131
+ height: 1px;
132
+ padding: 0;
133
+ margin: -1px;
134
+ overflow: hidden;
135
+ clip: rect(0, 0, 0, 0);
136
+ white-space: nowrap;
137
+ border: 0;
138
+ }
139
+
140
+ .payrails-billing-address-form .payrails-dynamic-element-input,
141
+ .payrails-billing-address-form .payrails-dynamic-element-select {
142
+ background-color: #ffffff;
143
+ border: 1px solid #e6e8eb;
144
+ border-radius: 8px;
145
+ padding: 12px 14px;
146
+ font-size: 14px;
147
+ color: #1f2733;
148
+ }
149
+
150
+ .payrails-billing-address-form .payrails-dynamic-element-input::placeholder {
151
+ color: #9aa0a6;
152
+ }
153
+
154
+ .payrails-billing-address-form
155
+ .payrails-dynamic-element-input:not(
156
+ .payrails-dynamic-element-input--readonly
157
+ ):focus,
158
+ .payrails-billing-address-form
159
+ .payrails-dynamic-element-select:not(
160
+ .payrails-dynamic-element-select--readonly
161
+ ):focus {
162
+ outline: none;
163
+ border-color: #cdd2da;
164
+ background-color: #ffffff;
165
+ box-shadow: none;
166
+ }
167
+
168
+ .payrails-billing-address-form
169
+ .payrails-dynamic-element-form-field.error
170
+ .payrails-dynamic-element-input,
171
+ .payrails-billing-address-form
172
+ .payrails-dynamic-element-form-field.error
173
+ .payrails-dynamic-element-select {
174
+ border-color: #f25226;
175
+ background-color: #fdecec;
176
+ }
177
+
178
+ .payrails-billing-address-form .payrails-dynamic-element-input--readonly,
179
+ .payrails-billing-address-form .payrails-dynamic-element-select--readonly {
180
+ background-color: #f5f6f8;
181
+ color: #6b7280;
182
+ cursor: not-allowed;
183
+ }
184
+
185
+ .payrails-dynamic-element-form {
186
+ display: flex;
187
+ flex-direction: column;
188
+ gap: 16px;
189
+ width: 100%;
190
+ }
191
+
192
+ .payrails-dynamic-element-form-field {
193
+ display: flex;
194
+ flex-direction: column;
195
+ gap: 4px;
196
+ width: 100%;
197
+ }
198
+
199
+ .payrails-dynamic-element-form-field-label {
200
+ font-size: 14px;
201
+ font-weight: 500;
202
+ color: #000000;
203
+ margin-bottom: 4px;
204
+ }
205
+
206
+ .payrails-dynamic-element-form-field-component {
207
+ width: 100%;
208
+ }
209
+
210
+ .payrails-dynamic-element-form-field-error {
211
+ font-size: 12px;
212
+ color: #ff0000;
213
+ margin-top: 4px;
214
+ display: none;
215
+ }
216
+
217
+ .payrails-dynamic-element-form-field.error
218
+ .payrails-dynamic-element-form-field-error {
219
+ display: block;
220
+ }
221
+
222
+ .payrails-dynamic-element-input {
223
+ width: 100%;
224
+ padding: 10px 16px;
225
+ border: 1px solid #eae8ee;
226
+ font-size: 14px;
227
+ color: #1d1d1d;
228
+ background-color: #fff;
229
+ box-sizing: border-box;
230
+ transition: border-color 0.2s ease;
231
+ }
232
+
233
+ .payrails-dynamic-element-input:focus {
234
+ outline: none;
235
+ border-color: #007bff;
236
+ box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
237
+ }
238
+
239
+ .payrails-dynamic-element-input:invalid {
240
+ border-color: #f25226;
241
+ background-color: #f9e1e1;
242
+ }
243
+
244
+ .payrails-dynamic-element-form-field.error .payrails-dynamic-element-input {
245
+ border-color: #f25226;
246
+ background-color: #f9e1e1;
247
+ }
248
+
249
+ .payrails-dynamic-element-input::placeholder {
250
+ color: grey;
251
+ opacity: 1;
252
+ }
253
+
254
+ .payrails-dynamic-element-select {
255
+ appearance: none;
256
+ -webkit-appearance: none;
257
+ -moz-appearance: none;
258
+ background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
259
+ background-repeat: no-repeat;
260
+ background-position: right 8px center;
261
+ width: 100%;
262
+ font-size: 14px;
263
+ color: #1d1d1d;
264
+ background-color: #fff;
265
+ box-sizing: border-box;
266
+ transition: border-color 0.2s ease;
267
+ padding: 10px 16px;
268
+ margin: 0;
269
+ border: 1px solid #eae8ee;
270
+ box-shadow: none;
271
+ cursor: pointer;
272
+ }
273
+
274
+ .payrails-dynamic-element-tabs {
275
+ display: flex;
276
+ flex-direction: row;
277
+ border: 1px solid #eae8ee;
278
+ padding: 4px;
279
+ background: transparent;
280
+ }
281
+
282
+ .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab {
283
+ border-radius: 0;
284
+ flex: 1;
285
+ background: white;
286
+ border: none;
287
+ outline: none;
288
+ font-size: 16px;
289
+ font-weight: 500;
290
+ color: #000000;
291
+ padding: 4px;
292
+ text-transform: unset;
293
+ cursor: pointer;
294
+ }
295
+
296
+ .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab.active {
297
+ background-color: #e0e5ed;
298
+ }
299
+
300
+ .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab:hover {
301
+ background-color: unset;
302
+ color: unset;
303
+ }
304
+
98
305
  .payrails-store-instrument-checkbox {
99
306
  margin-right: 4px;
100
307
  }
@@ -849,123 +1056,3 @@ button.payrails-lean-button {
849
1056
  #payrails-paypal-button-wrapper {
850
1057
  min-height: 44px;
851
1058
  }
852
-
853
- .payrails-dynamic-element-form {
854
- display: flex;
855
- flex-direction: column;
856
- gap: 16px;
857
- width: 100%;
858
- }
859
-
860
- .payrails-dynamic-element-form-field {
861
- display: flex;
862
- flex-direction: column;
863
- gap: 4px;
864
- width: 100%;
865
- }
866
-
867
- .payrails-dynamic-element-form-field-label {
868
- font-size: 14px;
869
- font-weight: 500;
870
- color: #000000;
871
- margin-bottom: 4px;
872
- }
873
-
874
- .payrails-dynamic-element-form-field-component {
875
- width: 100%;
876
- }
877
-
878
- .payrails-dynamic-element-form-field-error {
879
- font-size: 12px;
880
- color: #ff0000;
881
- margin-top: 4px;
882
- display: none;
883
- }
884
-
885
- .payrails-dynamic-element-form-field.error
886
- .payrails-dynamic-element-form-field-error {
887
- display: block;
888
- }
889
-
890
- .payrails-dynamic-element-input {
891
- width: 100%;
892
- padding: 10px 16px;
893
- border: 1px solid #eae8ee;
894
- font-size: 14px;
895
- color: #1d1d1d;
896
- background-color: #fff;
897
- box-sizing: border-box;
898
- transition: border-color 0.2s ease;
899
- }
900
-
901
- .payrails-dynamic-element-input:focus {
902
- outline: none;
903
- border-color: #007bff;
904
- box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.25);
905
- }
906
-
907
- .payrails-dynamic-element-input:invalid {
908
- border-color: #f25226;
909
- background-color: #f9e1e1;
910
- }
911
-
912
- .payrails-dynamic-element-form-field.error .payrails-dynamic-element-input {
913
- border-color: #f25226;
914
- background-color: #f9e1e1;
915
- }
916
-
917
- .payrails-dynamic-element-input::placeholder {
918
- color: grey;
919
- opacity: 1;
920
- }
921
-
922
- .payrails-dynamic-element-select {
923
- appearance: none;
924
- -webkit-appearance: none;
925
- -moz-appearance: none;
926
- background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
927
- background-repeat: no-repeat;
928
- background-position: right 8px center;
929
- width: 100%;
930
- font-size: 14px;
931
- color: #1d1d1d;
932
- background-color: #fff;
933
- box-sizing: border-box;
934
- transition: border-color 0.2s ease;
935
- padding: 10px 16px;
936
- margin: 0;
937
- border: 1px solid #eae8ee;
938
- box-shadow: none;
939
- cursor: pointer;
940
- }
941
-
942
- .payrails-dynamic-element-tabs {
943
- display: flex;
944
- flex-direction: row;
945
- border: 1px solid #eae8ee;
946
- padding: 4px;
947
- background: transparent;
948
- }
949
-
950
- .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab {
951
- border-radius: 0;
952
- flex: 1;
953
- background: white;
954
- border: none;
955
- outline: none;
956
- font-size: 16px;
957
- font-weight: 500;
958
- color: #000000;
959
- padding: 4px;
960
- text-transform: unset;
961
- cursor: pointer;
962
- }
963
-
964
- .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab.active {
965
- background-color: #e0e5ed;
966
- }
967
-
968
- .payrails-dynamic-element-tabs button.payrails-dynamic-element-tab:hover {
969
- background-color: unset;
970
- color: unset;
971
- }
package/payrails.d.ts CHANGED
@@ -4,6 +4,10 @@ type JSONSchemaType = JSONSchemaProperty & {
4
4
  required?: string[];
5
5
  dependentSchemas?: Record<string, JSONSchemaDependentSchema>;
6
6
  };
7
+ interface JSONSchemaOneOfOption {
8
+ const: string | number;
9
+ title: string;
10
+ }
7
11
  interface JSONSchemaDependentSchema {
8
12
  oneOf: Array<{
9
13
  properties: Record<string, {
@@ -24,17 +28,14 @@ interface JSONSchemaProperty {
24
28
  [UI_POSITION_FIELD]?: number;
25
29
  properties?: Record<string, JSONSchemaType>;
26
30
  }
27
- interface JSONSchemaOneOfOption {
28
- const: string | number;
29
- title: string;
30
- }
31
- interface JSONSchemaOneOfOption {
32
- const: string | number;
33
- title: string;
34
- }
35
31
  interface DynamicElementEvents {
36
- onReady: () => void;
37
- onValidationChange: (isValid: boolean) => void;
32
+ onReady?: () => void;
33
+ onValidationChange?: (isValid: boolean) => void;
34
+ }
35
+ interface DynamicElementFieldEvents {
36
+ onChange: (value: any) => void;
37
+ onReady: (initialValue: any) => void;
38
+ onBlur: () => void;
38
39
  }
39
40
  interface DynamicElementFieldTranslation {
40
41
  label?: string;
@@ -183,6 +184,14 @@ declare class WorkflowExecution {
183
184
  private static _response;
184
185
  static get response(): WorkflowExecutionResponse;
185
186
  static setResponse(response: WorkflowExecutionResponse): typeof WorkflowExecution;
187
+ /**
188
+ * Non-throwing read of the current execution id. Returns `undefined` when
189
+ * the workflow execution hasn't been initialized yet. Prefer this over
190
+ * `WorkflowExecution.response.id` in observational code paths (event
191
+ * emission, logging, analytics) where the workflow not being loaded should
192
+ * degrade gracefully instead of throwing.
193
+ */
194
+ static get executionId(): string | undefined;
186
195
  static get workflowCode(): string;
187
196
  static get lookup(): {
188
197
  httpCode: number;
@@ -572,6 +581,19 @@ interface SdkConfiguration {
572
581
  };
573
582
  execution?: WorkflowExecutionResponse;
574
583
  featureConfig?: SdkFeatureConfig;
584
+ morData?: MorData;
585
+ }
586
+ interface MorData {
587
+ billingLines?: {
588
+ street?: string;
589
+ line2?: string;
590
+ city?: string;
591
+ state?: string;
592
+ postalCode?: string;
593
+ email?: string;
594
+ country?: string;
595
+ form?: JSONSchemaType;
596
+ };
575
597
  }
576
598
  interface SdkFeatureConfig {
577
599
  gpayIframeRollout?: number;
@@ -1501,6 +1523,18 @@ declare enum AuthorizationFailureReasons {
1501
1523
  USER_CANCELLED = "USER_CANCELLED"
1502
1524
  }
1503
1525
 
1526
+ type BillingAddressPrefill = Omit<NonNullable<MorData['billingLines']>, 'form'>;
1527
+ interface BillingAddressFormOptions {
1528
+ schema: JSONSchemaType;
1529
+ title?: string;
1530
+ prefill?: BillingAddressPrefill;
1531
+ styles?: DynamicElementStyles;
1532
+ translations?: DynamicElementTranslations;
1533
+ events?: {
1534
+ onReady?: () => void;
1535
+ };
1536
+ }
1537
+
1504
1538
  interface AuthFailedMsgOptions {
1505
1539
  translations?: {
1506
1540
  label?: string;
@@ -1830,6 +1864,8 @@ declare class Dropin extends PayrailsElement {
1830
1864
  private paypal;
1831
1865
  private lean;
1832
1866
  private loadingScreen;
1867
+ private billingAddressForm;
1868
+ private billingValidationBlocked;
1833
1869
  constructor(collectContainer: PayrailsCollectContainer, clientConfig: PayrailsClientOptions, dropinConfig: DropinOptions);
1834
1870
  private get returnInfo();
1835
1871
  private isHppIntegration;
@@ -1847,6 +1883,7 @@ declare class Dropin extends PayrailsElement {
1847
1883
  private createApplePayButton;
1848
1884
  private createCardPaymentButton;
1849
1885
  private onAuthorizeSuccess;
1886
+ private validateBillingAddress;
1850
1887
  private getElementEvents;
1851
1888
  private onAuthorizePending;
1852
1889
  private getErrorMessage;
@@ -1902,6 +1939,7 @@ interface DropinOptions {
1902
1939
  mercadoPago?: GenericRedirectDropinOptions['translations'];
1903
1940
  revolutPay?: GenericRedirectDropinOptions['translations'];
1904
1941
  addressSelector?: AddressSelectorElementOptions['translations'];
1942
+ billingAddressForm?: BillingAddressFormOptions['translations'];
1905
1943
  applePayButton?: ApplePayDropinOptions['translations'];
1906
1944
  leanButton?: LeanDropinOptions['translations'];
1907
1945
  errorMessages?: {
@@ -1922,6 +1960,7 @@ interface DropinOptions {
1922
1960
  authFailed?: Partial<CSSStyleDeclaration>;
1923
1961
  loadingScreen?: LoadingScreenStyles;
1924
1962
  addressSelector?: AddressSelectorElementOptions['styles'];
1963
+ billingAddressForm?: BillingAddressFormOptions['styles'];
1925
1964
  mercadoPago?: GenericRedirectDropinOptions['styles'];
1926
1965
  revolutPay?: GenericRedirectDropinOptions['styles'];
1927
1966
  };
@@ -1934,11 +1973,28 @@ interface ContainerStyles {
1934
1973
  styles?: Partial<CSSStyleDeclaration>;
1935
1974
  }
1936
1975
 
1976
+ interface DynamicElementFieldOptions {
1977
+ id: string;
1978
+ name: string;
1979
+ required?: boolean;
1980
+ property: JSONSchemaProperty;
1981
+ label: string;
1982
+ placeholder: string;
1983
+ value?: string;
1984
+ readOnly?: boolean;
1985
+ errors: DynamicElementErrorTranslation;
1986
+ styles?: DynamicElementFieldStyles;
1987
+ events: DynamicElementFieldEvents;
1988
+ }
1989
+
1990
+ type FieldOptionsWithoutEvents = Omit<DynamicElementFieldOptions, 'events'>;
1991
+
1937
1992
  interface DynamicElementOptions {
1938
1993
  styles?: DynamicElementStyles;
1939
1994
  translations?: DynamicElementTranslations;
1940
- paymentMethod: BasePaymentMethodConfig;
1995
+ paymentMethod?: BasePaymentMethodConfig;
1941
1996
  events?: DynamicElementEvents;
1997
+ fieldOverrides?: Record<string, Partial<FieldOptionsWithoutEvents>>;
1942
1998
  }
1943
1999
  interface FormConfig {
1944
2000
  schema: JSONSchemaType;
@@ -1952,7 +2008,7 @@ declare class DynamicElementForm extends Tokenizable {
1952
2008
  private __schema;
1953
2009
  private _previousFormValidState;
1954
2010
  constructor(options: DynamicElementOptions, formConfig: FormConfig, returnInfo?: ReturnInfo | undefined);
1955
- protected collect(): Promise<Record<string, any>>;
2011
+ collect(): Promise<Record<string, any>>;
1956
2012
  protected constructSaveInstrumentBody(tokens: any, opts?: TokenizeOptions): Promise<any>;
1957
2013
  private isFormValid;
1958
2014
  private isFormValidSilent;
@@ -2088,6 +2144,30 @@ interface PayPalScriptConfig {
2088
2144
  locale?: string;
2089
2145
  }
2090
2146
 
2147
+ interface PaymentAttemptContext {
2148
+ readonly executionId: string;
2149
+ readonly paymentMethodCode: PaymentMethodCode;
2150
+ }
2151
+ declare enum ACTION_REQUIRED_KIND {
2152
+ GENERIC_REDIRECT = "genericRedirect",
2153
+ THREE_DS = "3ds"
2154
+ }
2155
+ type ActionRequiredKind = `${ACTION_REQUIRED_KIND}`;
2156
+ interface ActionRequiredEvent extends PaymentAttemptContext {
2157
+ readonly url: string;
2158
+ readonly kind: ActionRequiredKind;
2159
+ /**
2160
+ * Call to take over the action. The SDK will not perform its default
2161
+ * behavior (navigate, mount the 3DS popup).
2162
+ */
2163
+ preventDefault(): void;
2164
+ }
2165
+ type PayrailsEvents = {
2166
+ actionRequired: ActionRequiredEvent;
2167
+ };
2168
+ type PayrailsEventName = keyof PayrailsEvents;
2169
+ type PayrailsEventHandler<K extends PayrailsEventName> = (event: PayrailsEvents[K]) => void | Promise<void>;
2170
+
2091
2171
  interface QueryDefinition<T> {
2092
2172
  path: string[];
2093
2173
  returnType: T;
@@ -2151,11 +2231,13 @@ declare class Payrails {
2151
2231
  paypalButton(options?: PaypalButtonOptions): PaypalButton;
2152
2232
  leanButton(options: LeanButtonOptions): LeanButton;
2153
2233
  genericRedirectButton(options: GenericRedirectButtonOptions): GenericRedirectButton;
2154
- dynamicElement(options: DynamicElementOptions): DynamicElementForm;
2234
+ dynamicElement(options: DynamicElementOptions & Required<Pick<DynamicElementOptions, 'paymentMethod'>>): DynamicElementForm;
2155
2235
  getSavedPaypalAccounts(): StoredPaymentInstrument<PayPalMetadata>[];
2156
2236
  private logIntegrationMode;
2157
2237
  private constructor();
2158
2238
  private getContainerLayout;
2239
+ on<K extends PayrailsEventName>(name: K, handler: PayrailsEventHandler<K>): () => void;
2240
+ off<K extends PayrailsEventName>(name: K, handler: PayrailsEventHandler<K>): void;
2159
2241
  binLookup(): Promise<any>;
2160
2242
  }
2161
2243
  interface ClientEvents {
@@ -2281,5 +2363,5 @@ interface PayrailsClientOptions {
2281
2363
  };
2282
2364
  }
2283
2365
 
2284
- export { AuthorizationFailureReasons, ElementType, INTEGRATION_TYPE, PAYMENT_METHOD_CODES, Payrails, PayrailsCollectContainer, PayrailsEnvironment, REVOLUT_PAY_DEFAULT_LABEL, REVOLUT_PAY_DEFAULT_THEME };
2285
- export type { ApplePayButtonOptions, CardFormOptions, CardListOptions, CardPaymentButtonOptions, CollectContainerOptions, DropinOptions, ExecutionMeta, ExecutionMetaCustomer, ExecutionMetaKey, GenericRedirectButtonOptions, GooglePayButtonOptions, InitOptions, LeanButtonOptions, PaymentEvents, PaypalButtonOptions, PayrailsAmount, PayrailsClientOptions, PayrailsContainerType, PayrailsSecureField, PayrailsSecureFieldEvent, ReturnInfo, RevolutPayButtonTheme, RevolutPayStyles, SaveInstrumentResponse, StorablePaymentCompositionOption, WorkflowExecutionResponse };
2366
+ export { ACTION_REQUIRED_KIND, AuthorizationFailureReasons, ElementType, INTEGRATION_TYPE, PAYMENT_METHOD_CODES, Payrails, PayrailsCollectContainer, PayrailsEnvironment, REVOLUT_PAY_DEFAULT_LABEL, REVOLUT_PAY_DEFAULT_THEME };
2367
+ export type { ActionRequiredEvent, ActionRequiredKind, ApplePayButtonOptions, CardFormOptions, CardListOptions, CardPaymentButtonOptions, CollectContainerOptions, DropinOptions, ExecutionMeta, ExecutionMetaCustomer, ExecutionMetaKey, GenericRedirectButtonOptions, GooglePayButtonOptions, InitOptions, LeanButtonOptions, PaymentAttemptContext, PaymentEvents, PaypalButtonOptions, PayrailsAmount, PayrailsClientOptions, PayrailsContainerType, PayrailsEventHandler, PayrailsEventName, PayrailsEvents, PayrailsSecureField, PayrailsSecureFieldEvent, ReturnInfo, RevolutPayButtonTheme, RevolutPayStyles, SaveInstrumentResponse, StorablePaymentCompositionOption, WorkflowExecutionResponse };