@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.
- package/README.md +50 -13
- package/lib/commonjs/api/client.js +39 -0
- package/lib/commonjs/api/client.js.map +1 -1
- package/lib/commonjs/api/endpoints.js +3 -0
- package/lib/commonjs/api/endpoints.js.map +1 -1
- package/lib/commonjs/components/icons.js +19 -0
- package/lib/commonjs/components/icons.js.map +1 -1
- package/lib/commonjs/components/payment-button.js +53 -39
- package/lib/commonjs/components/payment-button.js.map +1 -1
- package/lib/commonjs/components/selection-sheet.js +393 -0
- package/lib/commonjs/components/selection-sheet.js.map +1 -0
- package/lib/commonjs/internal/format.js +11 -0
- package/lib/commonjs/internal/format.js.map +1 -1
- package/lib/module/api/client.js +39 -0
- package/lib/module/api/client.js.map +1 -1
- package/lib/module/api/endpoints.js +3 -0
- package/lib/module/api/endpoints.js.map +1 -1
- package/lib/module/components/icons.js +18 -0
- package/lib/module/components/icons.js.map +1 -1
- package/lib/module/components/payment-button.js +56 -42
- package/lib/module/components/payment-button.js.map +1 -1
- package/lib/module/components/selection-sheet.js +391 -0
- package/lib/module/components/selection-sheet.js.map +1 -0
- package/lib/module/internal/format.js +10 -0
- package/lib/module/internal/format.js.map +1 -1
- package/lib/typescript/api/client.d.ts +7 -1
- package/lib/typescript/api/client.d.ts.map +1 -1
- package/lib/typescript/api/endpoints.d.ts +3 -0
- package/lib/typescript/api/endpoints.d.ts.map +1 -1
- package/lib/typescript/components/icons.d.ts +1 -0
- package/lib/typescript/components/icons.d.ts.map +1 -1
- package/lib/typescript/components/payment-button.d.ts +3 -2
- package/lib/typescript/components/payment-button.d.ts.map +1 -1
- package/lib/typescript/components/selection-sheet.d.ts +25 -0
- package/lib/typescript/components/selection-sheet.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +1 -1
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/internal/format.d.ts +2 -0
- package/lib/typescript/internal/format.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +65 -2
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/api/client.ts +45 -0
- package/src/api/endpoints.ts +3 -0
- package/src/components/icons.tsx +14 -0
- package/src/components/payment-button.tsx +54 -38
- package/src/components/selection-sheet.tsx +383 -0
- package/src/index.ts +10 -0
- package/src/internal/format.ts +8 -0
- 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
|
|
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,
|
|
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
|
|
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
|
-
/**
|
|
49
|
-
|
|
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,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
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) {
|
package/src/api/endpoints.ts
CHANGED
|
@@ -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
|
});
|
package/src/components/icons.tsx
CHANGED
|
@@ -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 {
|
|
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
|
|
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
|
-
|
|
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 [
|
|
27
|
-
|
|
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
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
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
|
|
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
|
|
56
|
-
onPress={
|
|
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
|
|
70
|
+
opacity: disabled ? 0.6 : 1,
|
|
64
71
|
},
|
|
65
72
|
]}
|
|
66
73
|
>
|
|
67
|
-
{
|
|
68
|
-
|
|
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={
|
|
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={() =>
|
|
92
|
-
onClosed={
|
|
107
|
+
onRequestClose={() => setPaymentVisible(false)}
|
|
108
|
+
onClosed={handlePaymentClosed}
|
|
93
109
|
onSuccess={onSuccess}
|
|
94
110
|
onError={onError}
|
|
95
111
|
/>
|