@payabli/component-contracts 0.2.0 → 0.4.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 CHANGED
@@ -14,7 +14,7 @@ pnpm add @payabli/component-contracts
14
14
 
15
15
  - `protocol/`: the postMessage envelope, `parseEnvelope` / `parseMessage` /
16
16
  `parsePayload`, the base events every component emits, and the messages the
17
- SDK sends to the iframe (`CONFIG_SET`, `SESSION_UPDATE`, `SUBMIT`, ...).
17
+ SDK sends to the iframe (`CONFIG_SET`, `SUBMIT_REQUEST`, ...).
18
18
  - `payin/`: the PayIn component. Its options schema, event schemas, and the
19
19
  `PAYMENT_METHODS` / `CARD_BRANDS` vocabulary.
20
20
  - `registry`: `register()`, `getComponentDescriptor()`, and the
@@ -33,7 +33,7 @@ Prefill remains a generic capability that other components may support through `
33
33
  ### Session/init config
34
34
 
35
35
  The request is `POST /api/v2/{slug}/Session/init` with `platform: 'Web'`, `entryPoint`, `allowedParentOrigins`, and `components`.
36
- `GET /api/v2/Session/bootstrap` returns each component's config unchanged.
36
+ The iframe gets each component's config unchanged from the server session.
37
37
  Tenant identity, operation, payment amounts, customer data, and invoice data come only from the server session.
38
38
  The browser submit payload contains payment credentials, capture results, and the selected method, not business configuration.
39
39
 
@@ -303,12 +303,12 @@ The exported `FORM_METHODS` tuple defines the default order.
303
303
  Without overrides, the default order and initial method stay unchanged.
304
304
  The options schema rejects unknown method names and non-array orders. It accepts duplicates for the iframe to ignore.
305
305
  The SDK forwards options unchanged through `CONFIG_SET.options`. React uses the existing `options` prop, with no new props.
306
- `payin.update({ options: { initialMethod: 'card', methodOrder: ['card', 'ach'] } })` remounts the iframe.
306
+ `payin.update({ options: { initialMethod: 'card', methodOrder: ['card', 'ach'] } })` sends `CONFIG_SET` to the live frame. The frame stays in place.
307
307
  No new session is required. Layout, density, label style, and color scheme are unchanged.
308
308
 
309
309
  ### Appearance
310
310
 
311
- `appearance` is client-side. `update()` remounts the iframe without creating a new session.
311
+ `appearance` is client-side. `update()` applies it to the live frame without a new session. `locale` is part of the frame URL, so `update()` does not change it on a live frame.
312
312
 
313
313
  | Setting | Values and behavior |
314
314
  | ------------------- | ------------------------------------------------------------------------------------------------------------ |
@@ -386,16 +386,26 @@ const payin = payabli.create('payin', {
386
386
  #### Success and errors
387
387
 
388
388
  `success` and React's `onSuccess` report confirmed success only. `submit()` resolves with the same result data.
389
- `PayInSuccessPayload.transactionId` identifies a pay or auth transaction when present.
390
- The wire success data remains an open record. The SDK preserves fields it does not interpret.
391
389
 
392
- For tokenize sessions, `SUBMIT_RESULT.data`, the `success` event, and the `submit()` result contain:
390
+ > [!IMPORTANT]
391
+ > Confirm every outcome on your server with a webhook or a status call before you fulfill an order.
392
+ > Do not use the browser `success` event alone as proof of payment. Code on the page can fake it.
393
+
394
+ The payload is `PayInSuccessPayload`, one closed shape for every operation:
393
395
 
394
396
  ```ts
395
- { referenceId: string, customerId?: number, methodReferenceId?: string }
397
+ {
398
+ operation: 'pay' | 'auth' | 'tokenize',
399
+ method: 'card' | 'ach' | 'check' | 'applepay' | 'googlepay',
400
+ transactionId?: string, // pay, auth
401
+ storedMethodId?: string, // tokenize; pay or auth that saved the method
402
+ customerId?: number, // when the API created or matched a customer
403
+ paymentMethod?: { maskedAccount?, accountType?, expiration?, holderName? },
404
+ amount?: { total: number, serviceFee?: number, currency?: string }, // pay, auth
405
+ }
396
406
  ```
397
407
 
398
- `referenceId` is the saved payment method ID, not a transaction ID. `PayInSuccessPayload` declares it as an optional string.
408
+ `transactionId` is the Payabli transaction id. `storedMethodId` is the saved payment method id: pass it back as `storedMethodId` on a later payment. The API response body does not reach the page.
399
409
 
400
410
  A failed `SUBMIT_RESULT` rejects `submit()` and emits `error`, mapped to React's `onError`.
401
411
  Errors have `{ code, message, recoverable, details? }`. The SDK forwards the code and message unchanged.
@@ -407,7 +417,7 @@ Recoverable failures release the lock. Non-recoverable failures keep it locked.
407
417
  | ------------------------- | ----------------------------------------------------------------------------------------------------------- |
408
418
  | `SUBMIT_FAILED` | Confirmed decline or validation failure. Keep entered values and allow correction when `recoverable: true`. |
409
419
  | `OUTCOME_UNKNOWN` | The API did not confirm the result. A prior attempt may have processed. Do not retry this session. |
410
- | `SESSION_COMPLETED` | The session already succeeded. Create a new session. |
420
+ | `SESSION_COMPLETED` | This component already succeeded. The SDK emits `error` and removes this component. |
411
421
  | `UNSUPPORTED_OPERATION` | The session operation does not support this method. No payment API call occurs. |
412
422
  | `UNSUPPORTED_SAVE_METHOD` | Check cannot use `saveIfSuccess: true`. No payment API call occurs. |
413
423
 
@@ -441,16 +451,25 @@ In React, read `isValid` from `onChange`. Do not use `onReady` or `onRendered` a
441
451
 
442
452
  #### SDK and session errors
443
453
 
444
- | Code | Meaning and recovery |
445
- | ------------------------ | --------------------------------------------------------------------------------------------------------- |
446
- | `LOAD_TIMEOUT` | The iframe did not send READY within the timeout. The SDK retries loading once before reporting an error. |
447
- | `PROTOCOL_ERROR` | postMessage validation failed. |
448
- | `INVALID_STATE` | The operation targets a destroyed instance. |
449
- | `SESSION_EXPIRED` | The session reached its ceiling or refresh failed without recovery. Supply a new session. |
450
- | `SESSION_REFRESH_FAILED` | An individual auto-refresh attempt failed and is recoverable. |
451
- | `TOKEN_EXPIRED` | An iframe API call used an expired JWT. The SDK refreshes immediately without a public event. |
452
- | `RENDER_TOKEN_EXPIRED` | The frame URL no longer renders. The SDK rebuilds the frame and reports an error after the rebuild limit. |
453
- | `RENDER_TOKEN_INVALID` | Render token signature, audience, or format checks failed. Global `sessionError` requires a new session. |
454
+ | Code | Meaning and recovery |
455
+ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
456
+ | `LOAD_TIMEOUT` | The iframe did not send READY within the timeout. The SDK retries loading once before reporting an error. |
457
+ | `PROTOCOL_ERROR` | postMessage validation failed. |
458
+ | `INVALID_STATE` | The operation targets a destroyed instance. |
459
+ | `EXCHANGE_CODE_INVALID` | The frame could not redeem its exchange code: unknown, expired, used, or issued for another key. The SDK emits `error` and removes this component. Create a new session. |
460
+
461
+ Session errors go to `payabli.on('sessionExpired')` or `payabli.on('sessionError')`, not to the component `error` event.
462
+
463
+ | Code | Event | SDK action and recovery |
464
+ | ---------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------- |
465
+ | `SESSION_EXPIRED` | `sessionExpired` | Removes every frame. Create a new session and mount again. |
466
+ | `RENDER_TOKEN_EXPIRED` | `sessionExpired` | Removes every frame. The render token ends at the session ceiling. Create a new session and mount again. |
467
+ | `SESSION_REVOKED` | `sessionError` | Removes every frame. Create a new session and mount again. |
468
+ | `SESSION_COOKIE_UNAVAILABLE` | `sessionError` | Removes every frame. The browser did not return the session cookie to the frame. |
469
+ | `SESSION_LIMIT_REACHED` | `sessionError` | Removes every frame. Create a new session. |
470
+ | `SESSION_INVALID` | `sessionError` | Removes every frame. Create a new session. |
471
+ | `ORIGIN_NOT_ALLOWED` | `sessionError` | Removes every frame. Add the page origin to `allowedParentOrigins` and create a new session. |
472
+ | `RENDER_TOKEN_INVALID` | `sessionError` | Removes every frame. Render token signature, audience, or format checks failed. Create a new session. |
454
473
 
455
474
  ### Post-success lock and session replacement
456
475
 
@@ -466,14 +485,13 @@ After success, the component clears sensitive payment fields and locks all field
466
485
  Repeated submissions return `SESSION_COMPLETED` with `recoverable: false`.
467
486
  Both error codes pass unchanged to the `submit()` rejection and the `error` event, or React's `onError` callback.
468
487
 
469
- Call `payabli.updateSession(newSession)` with a newly created session to unlock the component.
470
- This sends `SESSION_UPDATE` with `replace: true`. A token refresh with `replace: false` does not unlock it.
488
+ Completion is per component key. After a successful PayIn submit, the SDK emits `success` and then removes only that PayIn component. Other components of the session stay usable, including another PayIn with a different key.
489
+ Render the next state of your page in the `success` handler. To take another payment, create a new session and a new `Payabli` instance.
471
490
 
472
491
  Wallet sheets and form submission share one in-flight lock. Closing a wallet sheet releases it.
473
492
  After success, the iframe clears card number, CVV, expiration, account number, routing number, and check capture.
474
493
  The server records session completion and rejects later submissions before any payment API call.
475
- A new bootstrap session ID also remounts the form with fresh state and the new session key.
476
- Appearance updates and token refreshes do not clear the server completion lock.
494
+ Appearance updates do not clear the server completion lock.
477
495
 
478
496
  The server stores attempt counters and completion records in Redis for the session lifetime. If Redis is unavailable, submission fails closed.
479
497
  GetPaid and Authorize cache each idempotency key for two minutes before processing, regardless of the result.
@@ -513,7 +531,7 @@ This is a pre-production breaking change. Remove obsolete configuration instead
513
531
  | Field label and placeholder text | Browser `appearance.labels` using the keys above. |
514
532
  | `appearance.mode` | `appearance.colorScheme`. |
515
533
  | Ready-means-valid behavior | Use `change.isValid` or React `onChange`. `ready` and `rendered` are lifecycle events. |
516
- | Repeated submit after success | Create a new session and call `payabli.updateSession(newSession)`. |
534
+ | Repeated submit after success | Create a new session and a new `Payabli` instance. |
517
535
 
518
536
  Pay and auth examples must supply non-null `customerData`. Use identifiers that match the paypoint's customer rules.
519
537
  An empty object passes session validation but does not guarantee that the payment API can resolve a customer.
package/dist/errors.d.ts CHANGED
@@ -8,26 +8,23 @@ export declare const ErrorCodes: {
8
8
  readonly OUTCOME_UNKNOWN: "OUTCOME_UNKNOWN";
9
9
  /** This session already completed an operation. Create a new session. */
10
10
  readonly SESSION_COMPLETED: "SESSION_COMPLETED";
11
+ /** The session reached its expiration ceiling. Create a new session and mount again. */
11
12
  readonly SESSION_EXPIRED: "SESSION_EXPIRED";
12
- readonly SESSION_REFRESH_FAILED: "SESSION_REFRESH_FAILED";
13
- /** Reported by an iframe whose call was rejected for an expired JWT. Triggers a refresh. */
14
- readonly TOKEN_EXPIRED: "TOKEN_EXPIRED";
15
- /**
16
- * Reported by an iframe whose render token no longer renders. The SDK recreates the frame
17
- * with the latest render token.
18
- */
13
+ /** The session was revoked. Terminal. */
14
+ readonly SESSION_REVOKED: "SESSION_REVOKED";
15
+ /** The session reached its expiration ceiling on the server. Terminal. */
16
+ readonly SESSION_LIMIT_REACHED: "SESSION_LIMIT_REACHED";
17
+ /** Unknown session, or one that names a component this API build lacks. Terminal. */
18
+ readonly SESSION_INVALID: "SESSION_INVALID";
19
+ /** The browser did not send the session cookie back to the frame. Terminal. */
20
+ readonly SESSION_COOKIE_UNAVAILABLE: "SESSION_COOKIE_UNAVAILABLE";
21
+ /** The exchange code is unknown, expired, already used, or issued for another key. */
22
+ readonly EXCHANGE_CODE_INVALID: "EXCHANGE_CODE_INVALID";
23
+ /** The render token expired at the session ceiling. Ends the session like SESSION_EXPIRED. */
19
24
  readonly RENDER_TOKEN_EXPIRED: "RENDER_TOKEN_EXPIRED";
20
25
  /** The render token failed signature, audience, or format checks. Needs a new session. */
21
26
  readonly RENDER_TOKEN_INVALID: "RENDER_TOKEN_INVALID";
22
- /** Refresh rejected: the page origin is not on the session's allowlist. Terminal. */
27
+ /** The page origin is not on the session's allowlist. Terminal. */
23
28
  readonly ORIGIN_NOT_ALLOWED: "ORIGIN_NOT_ALLOWED";
24
- /** Refresh rejected: the session was revoked (token reuse included). Terminal. */
25
- readonly SESSION_REVOKED: "SESSION_REVOKED";
26
- /** Refresh rejected: the session reached its expiration ceiling. Terminal. */
27
- readonly SESSION_LIMIT_REACHED: "SESSION_LIMIT_REACHED";
28
- /** Refresh rejected: unknown session, or one that names a component this API build lacks. Terminal. */
29
- readonly SESSION_INVALID: "SESSION_INVALID";
30
- /** Refresh could not mint a render token: server misconfiguration. Terminal regardless of status. */
31
- readonly RENDER_TOKEN_FAILED: "RENDER_TOKEN_FAILED";
32
29
  };
33
30
  export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
package/dist/index.js CHANGED
@@ -1475,9 +1475,8 @@ const eventEnvelopeSchema = object({
1475
1475
  source: literal(MESSAGE_SOURCE),
1476
1476
  version: literal(MESSAGE_VERSION),
1477
1477
  type: string(),
1478
- instanceId: string(),
1479
1478
  // Deliberately unvalidated here. A malformed payload must fail at the
1480
- // message schema, AFTER the instance is identified, so the failure comes
1479
+ // message schema, AFTER the sender is identified, so the failure comes
1481
1480
  // back as PROTOCOL_ERROR instead of being dropped as foreign traffic.
1482
1481
  payload: optional(unknown()),
1483
1482
  });
@@ -1640,7 +1639,8 @@ const baseInboundEvents = {
1640
1639
  */
1641
1640
  const outboundMessages = {
1642
1641
  CONFIG_SET: object({
1643
- sessionToken: string(),
1642
+ /** Single-use code the frame redeems at Payhub for its session cookie. */
1643
+ exchangeCode: string(),
1644
1644
  options: optional(record),
1645
1645
  appearance: optional(appearanceSchema),
1646
1646
  }),
@@ -1648,10 +1648,6 @@ const outboundMessages = {
1648
1648
  FOCUS_REQUEST: object({ field: optional(string()) }),
1649
1649
  BLUR_REQUEST: emptyPayload,
1650
1650
  SUBMIT_REQUEST: emptyPayload,
1651
- SESSION_UPDATE: object({
1652
- sessionToken: string(),
1653
- replace: optional(boolean()),
1654
- }),
1655
1651
  DESTROY: emptyPayload,
1656
1652
  PROTOCOL_ERROR: object({ originalType: string(), reason: string() }),
1657
1653
  };
@@ -1809,6 +1805,7 @@ const payInDescriptor = register({
1809
1805
  type: 'payin',
1810
1806
  displayName: 'PayIn',
1811
1807
  embedPath: '/embed/payin',
1808
+ endsOnSuccess: true,
1812
1809
  optionsSchema: payinOptionsSchema,
1813
1810
  eventSchemas: payInEventSchemas,
1814
1811
  });
@@ -1823,27 +1820,24 @@ const ErrorCodes = {
1823
1820
  OUTCOME_UNKNOWN: 'OUTCOME_UNKNOWN',
1824
1821
  /** This session already completed an operation. Create a new session. */
1825
1822
  SESSION_COMPLETED: 'SESSION_COMPLETED',
1823
+ /** The session reached its expiration ceiling. Create a new session and mount again. */
1826
1824
  SESSION_EXPIRED: 'SESSION_EXPIRED',
1827
- SESSION_REFRESH_FAILED: 'SESSION_REFRESH_FAILED',
1828
- /** Reported by an iframe whose call was rejected for an expired JWT. Triggers a refresh. */
1829
- TOKEN_EXPIRED: 'TOKEN_EXPIRED',
1830
- /**
1831
- * Reported by an iframe whose render token no longer renders. The SDK recreates the frame
1832
- * with the latest render token.
1833
- */
1825
+ /** The session was revoked. Terminal. */
1826
+ SESSION_REVOKED: 'SESSION_REVOKED',
1827
+ /** The session reached its expiration ceiling on the server. Terminal. */
1828
+ SESSION_LIMIT_REACHED: 'SESSION_LIMIT_REACHED',
1829
+ /** Unknown session, or one that names a component this API build lacks. Terminal. */
1830
+ SESSION_INVALID: 'SESSION_INVALID',
1831
+ /** The browser did not send the session cookie back to the frame. Terminal. */
1832
+ SESSION_COOKIE_UNAVAILABLE: 'SESSION_COOKIE_UNAVAILABLE',
1833
+ /** The exchange code is unknown, expired, already used, or issued for another key. */
1834
+ EXCHANGE_CODE_INVALID: 'EXCHANGE_CODE_INVALID',
1835
+ /** The render token expired at the session ceiling. Ends the session like SESSION_EXPIRED. */
1834
1836
  RENDER_TOKEN_EXPIRED: 'RENDER_TOKEN_EXPIRED',
1835
1837
  /** The render token failed signature, audience, or format checks. Needs a new session. */
1836
1838
  RENDER_TOKEN_INVALID: 'RENDER_TOKEN_INVALID',
1837
- /** Refresh rejected: the page origin is not on the session's allowlist. Terminal. */
1839
+ /** The page origin is not on the session's allowlist. Terminal. */
1838
1840
  ORIGIN_NOT_ALLOWED: 'ORIGIN_NOT_ALLOWED',
1839
- /** Refresh rejected: the session was revoked (token reuse included). Terminal. */
1840
- SESSION_REVOKED: 'SESSION_REVOKED',
1841
- /** Refresh rejected: the session reached its expiration ceiling. Terminal. */
1842
- SESSION_LIMIT_REACHED: 'SESSION_LIMIT_REACHED',
1843
- /** Refresh rejected: unknown session, or one that names a component this API build lacks. Terminal. */
1844
- SESSION_INVALID: 'SESSION_INVALID',
1845
- /** Refresh could not mint a render token: server misconfiguration. Terminal regardless of status. */
1846
- RENDER_TOKEN_FAILED: 'RENDER_TOKEN_FAILED',
1847
1841
  };
1848
1842
 
1849
1843
  const BASE_COMPONENT_EVENT_NAMES = [
@@ -92,13 +92,41 @@ export declare const payinEvents: {
92
92
  vendorId: z.ZodMiniString<string>;
93
93
  }, z.core.$strip>;
94
94
  };
95
+ /** The session operation the payload reports on. */
96
+ export type PayInOperation = 'pay' | 'auth' | 'tokenize';
95
97
  /**
96
- * SUBMIT_RESULT.data for PayIn. Open on purpose: the transaction result grows
97
- * fields the SDK does not interpret, and it forwards all of them.
98
+ * SUBMIT_RESULT.data for PayIn: the `success` event payload and the `submit()`
99
+ * result. One closed shape for every operation, so a partner handles the
100
+ * result without branching on the operation. payhub builds it from the API
101
+ * result; the API body itself never reaches the page.
98
102
  */
99
103
  export type PayInSuccessPayload = {
100
- /** The transaction ID for pay or auth sessions. */
104
+ operation: PayInOperation;
105
+ /** The method the buyer used. */
106
+ method: PaymentMethodName;
107
+ /** The Payabli transaction id. Present for `pay` and `auth`. */
101
108
  transactionId?: string;
102
- /** The saved payment method ID for tokenize sessions. */
103
- referenceId?: string;
104
- } & Record<string, unknown>;
109
+ /**
110
+ * The saved payment method id. Present for `tokenize`, and for `pay` or `auth`
111
+ * when the session saved the method. Pass it back as `storedMethodId` on a
112
+ * later payment.
113
+ */
114
+ storedMethodId?: string;
115
+ /** The Payabli customer id when the API created or matched a customer. */
116
+ customerId?: number;
117
+ paymentMethod?: {
118
+ /** The account with every digit but the last four hidden, for example `5XXXXXXXXXXX0055`. */
119
+ maskedAccount?: string;
120
+ /** The card brand (`mastercard`) or the bank account type (`checking`). */
121
+ accountType?: string;
122
+ /** The card expiration, `MM/YY`. */
123
+ expiration?: string;
124
+ holderName?: string;
125
+ };
126
+ /** The charged or authorized amount. Present for `pay` and `auth`. */
127
+ amount?: {
128
+ total: number;
129
+ serviceFee?: number;
130
+ currency?: string;
131
+ };
132
+ };
@@ -97,7 +97,7 @@ export type BaseInboundType = keyof typeof baseInboundEvents;
97
97
  */
98
98
  export declare const outboundMessages: {
99
99
  readonly CONFIG_SET: z.ZodMiniObject<{
100
- sessionToken: z.ZodMiniString<string>;
100
+ exchangeCode: z.ZodMiniString<string>;
101
101
  options: z.ZodMiniOptional<z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>>;
102
102
  appearance: z.ZodMiniOptional<z.ZodMiniObject<{
103
103
  layout: z.ZodMiniOptional<z.ZodMiniEnum<{
@@ -133,10 +133,6 @@ export declare const outboundMessages: {
133
133
  }, z.core.$strip>;
134
134
  readonly BLUR_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
135
135
  readonly SUBMIT_REQUEST: z.ZodMiniObject<{}, z.core.$strip>;
136
- readonly SESSION_UPDATE: z.ZodMiniObject<{
137
- sessionToken: z.ZodMiniString<string>;
138
- replace: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
139
- }, z.core.$strip>;
140
136
  readonly DESTROY: z.ZodMiniObject<{}, z.core.$strip>;
141
137
  readonly PROTOCOL_ERROR: z.ZodMiniObject<{
142
138
  originalType: z.ZodMiniString<string>;
@@ -16,7 +16,6 @@ export declare const eventEnvelopeSchema: z.ZodMiniObject<{
16
16
  source: z.ZodMiniLiteral<"payabli">;
17
17
  version: z.ZodMiniLiteral<1>;
18
18
  type: z.ZodMiniString<string>;
19
- instanceId: z.ZodMiniString<string>;
20
19
  payload: z.ZodMiniOptional<z.ZodMiniUnknown>;
21
20
  }, z.core.$strip>;
22
21
  export type EventEnvelope = z.infer<typeof eventEnvelopeSchema>;
@@ -27,6 +27,8 @@ export type ComponentDescriptor<T extends ComponentType = ComponentType> = {
27
27
  type: T;
28
28
  displayName: string;
29
29
  embedPath: `/embed/${string}`;
30
+ /** A successful submit ends this component, so the SDK destroys it after `success`. */
31
+ endsOnSuccess: boolean;
30
32
  /**
31
33
  * Wire schema for CONFIG_SET.options. Payhub parses the options payload
32
34
  * with this same object, so the partner-facing options type and the
package/dist/sdk.d.ts CHANGED
@@ -8,25 +8,37 @@
8
8
  */
9
9
  import type { ComponentEventKey, ComponentEventMap, ComponentOptions, ComponentType } from './registry.js';
10
10
  import type { AppearanceOptions } from './protocol/base.js';
11
+ /**
12
+ * The `data` of `POST /v2/{entryName}/Session/init`, passed through from the partner server.
13
+ * It holds no API credential: the session JWT stays on Payabli's servers.
14
+ */
11
15
  export interface Session {
12
- /** Session JWT returned by `POST /v2/{entryName}/Session/init`. */
13
- sessionToken: string;
16
+ sessionId: string;
14
17
  /**
15
- * Signed render token from the same response. The SDK puts it in the iframe URL as the
16
- * `rt` parameter, where it identifies the entrypoint and carries the origin allowlist.
17
- * It authenticates no API call. Every refresh returns a fresh one.
18
+ * Signed render token. The SDK puts it in the iframe URL as the `rt` parameter, where it
19
+ * identifies the entrypoint and carries the origin allowlist. It authenticates no API call.
18
20
  */
19
21
  renderToken: string;
20
- /** Organization or paypoint slug the session belongs to. Used to build the refresh URL. */
22
+ /**
23
+ * One single-use code per component key. Each frame redeems its code once, within 60
24
+ * seconds of `Session/init`, for a session cookie.
25
+ */
26
+ exchangeCodes: Record<string, string>;
27
+ /** Organization or paypoint slug the session belongs to. */
21
28
  entryName: string;
22
29
  environment: string;
23
- /** ISO 8601 expiry of `sessionToken`. The SDK refreshes at ~80% of the remaining time. */
30
+ /** ISO 8601 session ceiling. The SDK ends the session at this time. */
24
31
  expiresAt: string;
25
32
  }
26
33
  export interface PayabliConfig {
27
34
  session: Session;
28
35
  }
29
36
  export interface CreateOptions<T extends ComponentType = ComponentType> {
37
+ /**
38
+ * The component key from `Session/init`. Required when the session has more than one
39
+ * component. Defaults to the component type.
40
+ */
41
+ key?: string;
30
42
  appearance?: AppearanceOptions;
31
43
  options?: ComponentOptions<T>;
32
44
  prefill?: T extends 'payin' ? never : Record<string, string>;
@@ -70,7 +82,6 @@ export type PayabliInstance = {
70
82
  on: <K extends SessionEventKey>(event: K, handler: (payload: SessionEventMap[K]) => void, options?: {
71
83
  signal?: AbortSignal;
72
84
  }) => () => void;
73
- updateSession: (session: Session) => void;
74
85
  destroy: () => void;
75
86
  };
76
87
  export type PayabliConstructor = (config: PayabliConfig) => PayabliInstance;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payabli/component-contracts",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Wire schemas, component registry, and partner-facing types shared by the Payabli embedded components SDK and payhub.",
5
5
  "private": false,
6
6
  "license": "MIT",