@clockpay/react-native 1.0.0 → 1.0.1

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.
Files changed (50) hide show
  1. package/README.md +50 -13
  2. package/lib/commonjs/api/client.js +39 -0
  3. package/lib/commonjs/api/client.js.map +1 -1
  4. package/lib/commonjs/api/endpoints.js +3 -0
  5. package/lib/commonjs/api/endpoints.js.map +1 -1
  6. package/lib/commonjs/components/icons.js +19 -0
  7. package/lib/commonjs/components/icons.js.map +1 -1
  8. package/lib/commonjs/components/payment-button.js +53 -39
  9. package/lib/commonjs/components/payment-button.js.map +1 -1
  10. package/lib/commonjs/components/selection-sheet.js +393 -0
  11. package/lib/commonjs/components/selection-sheet.js.map +1 -0
  12. package/lib/commonjs/internal/format.js +11 -0
  13. package/lib/commonjs/internal/format.js.map +1 -1
  14. package/lib/module/api/client.js +39 -0
  15. package/lib/module/api/client.js.map +1 -1
  16. package/lib/module/api/endpoints.js +3 -0
  17. package/lib/module/api/endpoints.js.map +1 -1
  18. package/lib/module/components/icons.js +18 -0
  19. package/lib/module/components/icons.js.map +1 -1
  20. package/lib/module/components/payment-button.js +56 -42
  21. package/lib/module/components/payment-button.js.map +1 -1
  22. package/lib/module/components/selection-sheet.js +391 -0
  23. package/lib/module/components/selection-sheet.js.map +1 -0
  24. package/lib/module/internal/format.js +10 -0
  25. package/lib/module/internal/format.js.map +1 -1
  26. package/lib/typescript/api/client.d.ts +7 -1
  27. package/lib/typescript/api/client.d.ts.map +1 -1
  28. package/lib/typescript/api/endpoints.d.ts +3 -0
  29. package/lib/typescript/api/endpoints.d.ts.map +1 -1
  30. package/lib/typescript/components/icons.d.ts +1 -0
  31. package/lib/typescript/components/icons.d.ts.map +1 -1
  32. package/lib/typescript/components/payment-button.d.ts +3 -2
  33. package/lib/typescript/components/payment-button.d.ts.map +1 -1
  34. package/lib/typescript/components/selection-sheet.d.ts +25 -0
  35. package/lib/typescript/components/selection-sheet.d.ts.map +1 -0
  36. package/lib/typescript/index.d.ts +1 -1
  37. package/lib/typescript/index.d.ts.map +1 -1
  38. package/lib/typescript/internal/format.d.ts +2 -0
  39. package/lib/typescript/internal/format.d.ts.map +1 -1
  40. package/lib/typescript/types.d.ts +65 -2
  41. package/lib/typescript/types.d.ts.map +1 -1
  42. package/package.json +1 -1
  43. package/src/api/client.ts +45 -0
  44. package/src/api/endpoints.ts +3 -0
  45. package/src/components/icons.tsx +14 -0
  46. package/src/components/payment-button.tsx +54 -38
  47. package/src/components/selection-sheet.tsx +383 -0
  48. package/src/index.ts +10 -0
  49. package/src/internal/format.ts +8 -0
  50. package/src/types.ts +75 -2
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/icons.tsx"],"names":[],"mappings":"AAEA,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0BAA0B;AAC1B,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAahD;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAE,SAAS,+BAiBpE;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAE,SAAS,+BAmBnE;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAWhD;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAajD"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../../src/components/icons.tsx"],"names":[],"mappings":"AAEA,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0BAA0B;AAC1B,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAahD;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAE,SAAS,+BAiBpE;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAE,SAAS,+BAmBnE;AAED,wBAAgB,QAAQ,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAWhD;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAS,EAAE,KAAiB,EAAE,EAAE,SAAS,+BAY1E;AAED,wBAAgB,SAAS,CAAC,EAAE,IAAS,EAAE,EAAE,SAAS,+BAajD"}
@@ -1,7 +1,8 @@
1
1
  import type { PaymentButtonProps } from '../types';
2
2
  /**
3
3
  * Drop-in payment button for React Native. Renders a "Pay with Clockpay" trigger
4
- * that initiates a checkout and opens a Stripe-style bottom-sheet payment modal.
4
+ * that opens a coin/network selection sheet, generates a payment link, then opens
5
+ * a Stripe-style bottom-sheet payment modal.
5
6
  */
6
- export declare function PaymentButton({ publicKey, clientSecret, appearance, label, disabled, apiBaseUrl, redirectUrl, onSuccess, onError, onClose, }: PaymentButtonProps): import("react").JSX.Element;
7
+ export declare function PaymentButton({ publicKey, amount, currency, reference, meta, appearance, label, disabled, apiBaseUrl, redirectUrl, onSuccess, onError, onClose, }: PaymentButtonProps): import("react").JSX.Element;
7
8
  //# sourceMappingURL=payment-button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"payment-button.d.ts","sourceRoot":"","sources":["../../../src/components/payment-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAMjE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAA2B,EAC3B,QAAQ,EACR,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,OAAO,GACR,EAAE,kBAAkB,+BA2EpB"}
1
+ {"version":3,"file":"payment-button.d.ts","sourceRoot":"","sources":["../../../src/components/payment-button.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAMjE;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,UAAU,EACV,KAA2B,EAC3B,QAAQ,EACR,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,OAAO,GACR,EAAE,kBAAkB,+BAuFpB"}
@@ -0,0 +1,25 @@
1
+ import type { CheckoutCurrency, CheckoutData, CheckoutMeta } from '../types';
2
+ import type { ResolvedTheme } from '../internal/theme';
3
+ interface SelectionSheetProps {
4
+ visible: boolean;
5
+ publicKey: string;
6
+ apiBaseUrl?: string;
7
+ theme: ResolvedTheme;
8
+ amount: number;
9
+ currency: CheckoutCurrency;
10
+ reference: string;
11
+ meta: CheckoutMeta;
12
+ onRequestClose: () => void;
13
+ onClosed: () => void;
14
+ onProceed: (checkout: CheckoutData) => void;
15
+ onError?: (error: Error) => void;
16
+ }
17
+ /**
18
+ * First step of the payment flow: the buyer picks a coin and then a settlement
19
+ * network. On continue, a payment link is generated (`create-link`) and the
20
+ * resulting checkout initiated, handing a {@link CheckoutData} to the caller so
21
+ * the payment sheet can open.
22
+ */
23
+ export declare function SelectionSheet({ visible, publicKey, apiBaseUrl, theme, amount, currency, reference, meta, onRequestClose, onClosed, onProceed, onError, }: SelectionSheetProps): import("react").JSX.Element;
24
+ export {};
25
+ //# sourceMappingURL=selection-sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-sheet.d.ts","sourceRoot":"","sources":["../../../src/components/selection-sheet.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,YAAY,EAGb,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAgBvD,UAAU,mBAAmB;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAClC;AAqFD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,SAAS,EACT,UAAU,EACV,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,cAAc,EACd,QAAQ,EACR,SAAS,EACT,OAAO,GACR,EAAE,mBAAmB,+BA2JrB"}
@@ -1,3 +1,3 @@
1
1
  export { PaymentButton } from './components/payment-button';
2
- export type { PaymentButtonProps, ClockPayAppearance, ClockPayEnvironment, CheckoutData, CheckoutResponse, VerifyCryptoPayload, VerifyCryptoResponse, } from './types';
2
+ export type { PaymentButtonProps, ClockPayAppearance, ClockPayEnvironment, CheckoutCurrency, CheckoutMeta, CheckoutPhoneNumber, CheckoutData, CheckoutResponse, Coin, CoinsResponse, Network, NetworksResponse, CreateLinkPayload, CreateLinkData, CreateLinkResponse, VerifyCryptoPayload, VerifyCryptoResponse, } from './types';
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,IAAI,EACJ,aAAa,EACb,OAAO,EACP,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,SAAS,CAAC"}
@@ -1,5 +1,7 @@
1
1
  /** Formats a number of seconds as `MM:SS`. */
2
2
  export declare function formatTime(totalSeconds: number): string;
3
+ /** Formats a fiat amount with its currency symbol, e.g. `formatMoney(20000, 'ngn')` → `₦20,000`. */
4
+ export declare function formatMoney(amount: number, currency: string): string;
3
5
  /** Resolves the on-chain code used to verify a transaction for a given checkout. */
4
6
  export declare function resolveNetworkCode(network?: string, fallback?: string): string;
5
7
  /** Truncates a long address for compact display: `0x1234…abcd`. */
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/internal/format.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAK,EAAE,IAAI,SAAI,GAAG,MAAM,CAGzE"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/internal/format.ts"],"names":[],"mappings":"AAEA,8CAA8C;AAC9C,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAKvD;AAID,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAG9E;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,SAAK,EAAE,IAAI,SAAI,GAAG,MAAM,CAGzE"}
@@ -19,6 +19,63 @@ export interface ClockPayAppearance {
19
19
  }
20
20
  /** The environment a public key belongs to. */
21
21
  export type ClockPayEnvironment = 'test' | 'live';
22
+ /** Fiat currency the order amount is denominated in. */
23
+ export type CheckoutCurrency = 'ngn' | 'usd';
24
+ /** A coin the buyer can pay with, from `GET /wallet/checkout/coins`. */
25
+ export interface Coin {
26
+ id: string;
27
+ name: string;
28
+ image: string;
29
+ code: string;
30
+ }
31
+ /** A settlement network for a coin, from `GET /wallet/checkout/networks/{coinId}`. */
32
+ export interface Network {
33
+ id: string;
34
+ tag: string;
35
+ code: string;
36
+ name: string;
37
+ }
38
+ export interface CoinsResponse {
39
+ data: Coin[];
40
+ }
41
+ export interface NetworksResponse {
42
+ data: Network[];
43
+ }
44
+ /** Buyer's phone number, split into dialling code and local number. */
45
+ export interface CheckoutPhoneNumber {
46
+ code: string;
47
+ number: string;
48
+ }
49
+ /** Order/buyer details the business provides for the payment link. */
50
+ export interface CheckoutMeta {
51
+ title: string;
52
+ description: string;
53
+ /** Buyer email. Optional. */
54
+ email?: string;
55
+ /** Business's own id for the buyer. Optional. */
56
+ customerId?: string;
57
+ fullName: string;
58
+ /** Buyer phone number. Optional. */
59
+ phoneNumber?: CheckoutPhoneNumber;
60
+ }
61
+ /** Body for `POST /payment/client/create-link`. */
62
+ export interface CreateLinkPayload {
63
+ amount: number;
64
+ currency: CheckoutCurrency;
65
+ coinId: string;
66
+ networkId: string;
67
+ reference: string;
68
+ meta: CheckoutMeta;
69
+ }
70
+ /** The generated payment link — its reference and single-use client secret. */
71
+ export interface CreateLinkData {
72
+ reference: string;
73
+ clientSecret: string;
74
+ }
75
+ export interface CreateLinkResponse {
76
+ message: string;
77
+ data: CreateLinkData;
78
+ }
22
79
  /** Payload returned by the checkout endpoint and rendered inside the sheet. */
23
80
  export interface CheckoutData {
24
81
  reference: string;
@@ -45,8 +102,14 @@ export interface VerifyCryptoResponse {
45
102
  export interface PaymentButtonProps {
46
103
  /** Public key from the business developer dashboard (e.g. `cpay_test_pk_...`). Required. */
47
104
  publicKey: string;
48
- /** Client secret returned from your server-side checkout call. Required. */
49
- clientSecret: string;
105
+ /** Order amount in the given `currency`. Required. */
106
+ amount: number;
107
+ /** Fiat currency of the `amount`. Required. */
108
+ currency: CheckoutCurrency;
109
+ /** Your own reference for this order. Required. */
110
+ reference: string;
111
+ /** Order and buyer details. The business supplies these; the buyer only picks a coin & network. Required. */
112
+ meta: CheckoutMeta;
50
113
  /** Visual customization for the button and sheet. */
51
114
  appearance?: ClockPayAppearance;
52
115
  /** Button label. Defaults to "Pay with Clockpay". */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,+CAA+C;AAC/C,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,+EAA+E;AAC/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,4FAA4F;IAC5F,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,qDAAqD;IACrD,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACjD,6DAA6D;IAC7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clockpay/react-native",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "A type-safe React Native SDK for accepting crypto payments with ClockPay — a Stripe-style bottom-sheet payment modal.",
5
5
  "license": "MIT",
6
6
  "author": "ClockPay",
package/src/api/client.ts CHANGED
@@ -3,6 +3,13 @@ import { endpoints } from './endpoints';
3
3
  import { resolveApiBaseUrl } from '../internal/constants';
4
4
  import type {
5
5
  CheckoutResponse,
6
+ Coin,
7
+ CoinsResponse,
8
+ CreateLinkData,
9
+ CreateLinkPayload,
10
+ CreateLinkResponse,
11
+ Network,
12
+ NetworksResponse,
6
13
  VerifyCryptoPayload,
7
14
  VerifyCryptoResponse,
8
15
  } from '../types';
@@ -43,6 +50,44 @@ export class ClockPayClient {
43
50
  });
44
51
  }
45
52
 
53
+ /** Lists the coins a buyer can pay with. */
54
+ async getCoins(): Promise<Coin[]> {
55
+ try {
56
+ const { data } = await this.http.get<CoinsResponse>(endpoints.coins);
57
+ return data.data;
58
+ } catch (error) {
59
+ throw toError(error, 'Failed to load coins.');
60
+ }
61
+ }
62
+
63
+ /** Lists the settlement networks available for a given coin. */
64
+ async getNetworks(coinId: string): Promise<Network[]> {
65
+ if (!coinId) {
66
+ throw new Error('ClockPay: a coinId is required.');
67
+ }
68
+ try {
69
+ const { data } = await this.http.get<NetworksResponse>(
70
+ `${endpoints.networks}/${coinId}`
71
+ );
72
+ return data.data;
73
+ } catch (error) {
74
+ throw toError(error, 'Failed to load networks.');
75
+ }
76
+ }
77
+
78
+ /** Generates a payment link, returning its reference and client secret. */
79
+ async createLink(payload: CreateLinkPayload): Promise<CreateLinkData> {
80
+ try {
81
+ const { data } = await this.http.post<CreateLinkResponse>(
82
+ endpoints.createLink,
83
+ payload
84
+ );
85
+ return data.data;
86
+ } catch (error) {
87
+ throw toError(error, 'Failed to create payment link.');
88
+ }
89
+ }
90
+
46
91
  /** Initiates a checkout for the given client secret. */
47
92
  async initiatePayment(clientSecret: string): Promise<CheckoutResponse> {
48
93
  if (!clientSecret) {
@@ -1,4 +1,7 @@
1
1
  export const endpoints = Object.freeze({
2
+ coins: '/wallet/client/checkout/coins',
3
+ networks: '/wallet/client/checkout/networks',
4
+ createLink: '/payment/client/create-link',
2
5
  initiatePayment: '/payment/client/checkout',
3
6
  verifyCrypto: '/transactions/verify-crypto',
4
7
  });
@@ -74,6 +74,20 @@ export function InfoIcon({ size = 16 }: IconProps) {
74
74
  );
75
75
  }
76
76
 
77
+ export function ChevronDownIcon({ size = 20, color = '#94a3b8' }: IconProps) {
78
+ return (
79
+ <Svg width={size} height={size} viewBox='0 0 24 24' fill='none'>
80
+ <Path
81
+ d='M6 9L12 15L18 9'
82
+ stroke={color}
83
+ strokeWidth={2}
84
+ strokeLinecap='round'
85
+ strokeLinejoin='round'
86
+ />
87
+ </Svg>
88
+ );
89
+ }
90
+
77
91
  export function CheckIcon({ size = 48 }: IconProps) {
78
92
  return (
79
93
  <Svg width={size} height={size} viewBox='0 0 24 24' fill='none'>
@@ -1,18 +1,22 @@
1
- import { useMemo, useState } from 'react';
2
- import { ActivityIndicator, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
1
+ import { useMemo, useRef, useState } from 'react';
2
+ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
3
  import type { CheckoutData, PaymentButtonProps } from '../types';
4
- import { ClockPayClient } from '../api/client';
5
4
  import { resolveTheme } from '../internal/theme';
5
+ import { SelectionSheet } from './selection-sheet';
6
6
  import { PaymentSheet } from './payment-sheet';
7
7
  import { LogoIcon } from './icons';
8
8
 
9
9
  /**
10
10
  * Drop-in payment button for React Native. Renders a "Pay with Clockpay" trigger
11
- * that initiates a checkout and opens a Stripe-style bottom-sheet payment modal.
11
+ * that opens a coin/network selection sheet, generates a payment link, then opens
12
+ * a Stripe-style bottom-sheet payment modal.
12
13
  */
13
14
  export function PaymentButton({
14
15
  publicKey,
15
- clientSecret,
16
+ amount,
17
+ currency,
18
+ reference,
19
+ meta,
16
20
  appearance,
17
21
  label = 'Pay with Clockpay',
18
22
  disabled,
@@ -22,28 +26,31 @@ export function PaymentButton({
22
26
  onError,
23
27
  onClose,
24
28
  }: PaymentButtonProps) {
29
+ const [selecting, setSelecting] = useState(false);
25
30
  const [checkout, setCheckout] = useState<CheckoutData | null>(null);
26
- const [visible, setVisible] = useState(false);
27
- const [loading, setLoading] = useState(false);
31
+ const [paymentVisible, setPaymentVisible] = useState(false);
32
+ // Holds the checkout produced by the selection sheet until it finishes closing,
33
+ // so the two sheets never present at the same time.
34
+ const pending = useRef<CheckoutData | null>(null);
28
35
 
29
36
  const theme = useMemo(() => resolveTheme(appearance), [appearance]);
30
37
 
31
- const initiate = async () => {
32
- if (loading) return;
33
- setLoading(true);
34
- try {
35
- const client = new ClockPayClient(publicKey, apiBaseUrl);
36
- const response = await client.initiatePayment(clientSecret);
37
- setCheckout(response.data);
38
- setVisible(true);
39
- } catch (error) {
40
- onError?.(error instanceof Error ? error : new Error('Payment initialization failed.'));
41
- } finally {
42
- setLoading(false);
38
+ const handleProceed = (data: CheckoutData) => {
39
+ pending.current = data;
40
+ setSelecting(false); // animate the selection sheet out first
41
+ };
42
+
43
+ const handleSelectionClosed = () => {
44
+ if (pending.current) {
45
+ setCheckout(pending.current);
46
+ pending.current = null;
47
+ setPaymentVisible(true);
48
+ } else {
49
+ onClose?.();
43
50
  }
44
51
  };
45
52
 
46
- const handleClosed = () => {
53
+ const handlePaymentClosed = () => {
47
54
  setCheckout(null);
48
55
  onClose?.();
49
56
  };
@@ -52,44 +59,53 @@ export function PaymentButton({
52
59
  <View>
53
60
  <TouchableOpacity
54
61
  activeOpacity={0.8}
55
- disabled={disabled || loading}
56
- onPress={initiate}
62
+ disabled={disabled}
63
+ onPress={() => setSelecting(true)}
57
64
  style={[
58
65
  styles.button,
59
66
  {
60
67
  backgroundColor: theme.buttonBg,
61
68
  borderColor: theme.buttonBorder,
62
69
  borderRadius: theme.radius,
63
- opacity: disabled || loading ? 0.6 : 1,
70
+ opacity: disabled ? 0.6 : 1,
64
71
  },
65
72
  ]}
66
73
  >
67
- {loading ? (
68
- <ActivityIndicator size='small' color={theme.buttonFg} />
74
+ <LogoIcon size={16} />
75
+ {typeof label === 'string' ? (
76
+ <Text style={[styles.label, { color: theme.buttonFg, fontFamily: theme.fontFamily }]}>
77
+ {label}
78
+ </Text>
69
79
  ) : (
70
- <>
71
- <LogoIcon size={16} />
72
- {typeof label === 'string' ? (
73
- <Text style={[styles.label, { color: theme.buttonFg, fontFamily: theme.fontFamily }]}>
74
- {label}
75
- </Text>
76
- ) : (
77
- label
78
- )}
79
- </>
80
+ label
80
81
  )}
81
82
  </TouchableOpacity>
82
83
 
84
+ <SelectionSheet
85
+ visible={selecting}
86
+ publicKey={publicKey}
87
+ apiBaseUrl={apiBaseUrl}
88
+ theme={theme}
89
+ amount={amount}
90
+ currency={currency}
91
+ reference={reference}
92
+ meta={meta}
93
+ onRequestClose={() => setSelecting(false)}
94
+ onClosed={handleSelectionClosed}
95
+ onProceed={handleProceed}
96
+ onError={onError}
97
+ />
98
+
83
99
  {checkout && (
84
100
  <PaymentSheet
85
- visible={visible}
101
+ visible={paymentVisible}
86
102
  checkout={checkout}
87
103
  publicKey={publicKey}
88
104
  apiBaseUrl={apiBaseUrl}
89
105
  theme={theme}
90
106
  redirectUrl={redirectUrl}
91
- onRequestClose={() => setVisible(false)}
92
- onClosed={handleClosed}
107
+ onRequestClose={() => setPaymentVisible(false)}
108
+ onClosed={handlePaymentClosed}
93
109
  onSuccess={onSuccess}
94
110
  onError={onError}
95
111
  />