@heyama/pay-react-native 0.0.0-stage → 1.0.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.
Files changed (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +99 -2
  3. package/assets/fonts/Figtree-Bold.ttf +0 -0
  4. package/assets/fonts/Figtree-ExtraBold.ttf +0 -0
  5. package/assets/fonts/Figtree-Medium.ttf +0 -0
  6. package/assets/fonts/Figtree-Regular.ttf +0 -0
  7. package/assets/fonts/Figtree-SemiBold.ttf +0 -0
  8. package/assets/fonts/OFL.txt +93 -0
  9. package/assets/logos/apple-pay.png +0 -0
  10. package/assets/logos/card.png +0 -0
  11. package/assets/logos/google-pay.png +0 -0
  12. package/assets/logos/mastercard.png +0 -0
  13. package/assets/logos/mixx.png +0 -0
  14. package/assets/logos/moov.png +0 -0
  15. package/assets/logos/mtn.png +0 -0
  16. package/assets/logos/orange.png +0 -0
  17. package/assets/logos/paypal.png +0 -0
  18. package/assets/logos/visa.png +0 -0
  19. package/assets/logos/wave.png +0 -0
  20. package/dist/checkout-core/hooks/use-checkout-controller.d.ts +9 -0
  21. package/dist/checkout-core/hooks/use-checkout-controller.js +319 -0
  22. package/dist/checkout-core/hooks/use-checkout-timers.d.ts +15 -0
  23. package/dist/checkout-core/hooks/use-checkout-timers.js +44 -0
  24. package/dist/checkout-core/hooks/use-phone-number.d.ts +7 -0
  25. package/dist/checkout-core/hooks/use-phone-number.js +82 -0
  26. package/dist/checkout-core/messages/en.d.ts +252 -0
  27. package/dist/checkout-core/messages/en.js +242 -0
  28. package/dist/checkout-core/messages/fr.d.ts +4 -0
  29. package/dist/checkout-core/messages/fr.js +244 -0
  30. package/dist/checkout-core/models/checkout.card.utils.d.ts +22 -0
  31. package/dist/checkout-core/models/checkout.card.utils.js +101 -0
  32. package/dist/checkout-core/models/checkout.constants.d.ts +56 -0
  33. package/dist/checkout-core/models/checkout.constants.js +142 -0
  34. package/dist/checkout-core/models/checkout.enum.d.ts +131 -0
  35. package/dist/checkout-core/models/checkout.enum.js +148 -0
  36. package/dist/checkout-core/models/checkout.interface.d.ts +417 -0
  37. package/dist/checkout-core/models/checkout.interface.js +1 -0
  38. package/dist/checkout-core/models/checkout.money.utils.d.ts +7 -0
  39. package/dist/checkout-core/models/checkout.money.utils.js +21 -0
  40. package/dist/checkout-core/models/checkout.phone.utils.d.ts +33 -0
  41. package/dist/checkout-core/models/checkout.phone.utils.js +159 -0
  42. package/dist/checkout-core/models/checkout.view.utils.d.ts +34 -0
  43. package/dist/checkout-core/models/checkout.view.utils.js +205 -0
  44. package/dist/checkout-core/models/domain.enum.d.ts +56 -0
  45. package/dist/checkout-core/models/domain.enum.js +62 -0
  46. package/dist/components/BrissotoPayProvider.d.ts +6 -0
  47. package/dist/components/BrissotoPayProvider.js +41 -0
  48. package/dist/components/PaymentSheetModal.d.ts +8 -0
  49. package/dist/components/PaymentSheetModal.js +72 -0
  50. package/dist/components/SheetBone.d.ts +3 -0
  51. package/dist/components/SheetBone.js +12 -0
  52. package/dist/components/SheetButton.d.ts +3 -0
  53. package/dist/components/SheetButton.js +33 -0
  54. package/dist/components/SheetCardFields.d.ts +8 -0
  55. package/dist/components/SheetCardFields.js +66 -0
  56. package/dist/components/SheetCodeField.d.ts +8 -0
  57. package/dist/components/SheetCodeField.js +95 -0
  58. package/dist/components/SheetContent.d.ts +3 -0
  59. package/dist/components/SheetContent.js +106 -0
  60. package/dist/components/SheetFailed.d.ts +3 -0
  61. package/dist/components/SheetFailed.js +43 -0
  62. package/dist/components/SheetForm.d.ts +7 -0
  63. package/dist/components/SheetForm.js +100 -0
  64. package/dist/components/SheetHeader.d.ts +6 -0
  65. package/dist/components/SheetHeader.js +69 -0
  66. package/dist/components/SheetIcon.d.ts +3 -0
  67. package/dist/components/SheetIcon.js +70 -0
  68. package/dist/components/SheetLayout.d.ts +8 -0
  69. package/dist/components/SheetLayout.js +35 -0
  70. package/dist/components/SheetLogo.d.ts +3 -0
  71. package/dist/components/SheetLogo.js +20 -0
  72. package/dist/components/SheetMessage.d.ts +3 -0
  73. package/dist/components/SheetMessage.js +15 -0
  74. package/dist/components/SheetMethodCard.d.ts +3 -0
  75. package/dist/components/SheetMethodCard.js +39 -0
  76. package/dist/components/SheetPhoneField.d.ts +3 -0
  77. package/dist/components/SheetPhoneField.js +56 -0
  78. package/dist/components/SheetRow.d.ts +3 -0
  79. package/dist/components/SheetRow.js +28 -0
  80. package/dist/components/SheetSimulator.d.ts +6 -0
  81. package/dist/components/SheetSimulator.js +39 -0
  82. package/dist/components/SheetSkeleton.d.ts +5 -0
  83. package/dist/components/SheetSkeleton.js +23 -0
  84. package/dist/components/SheetSuccess.d.ts +3 -0
  85. package/dist/components/SheetSuccess.js +51 -0
  86. package/dist/components/SheetSummary.d.ts +3 -0
  87. package/dist/components/SheetSummary.js +32 -0
  88. package/dist/components/SheetTerminal.d.ts +3 -0
  89. package/dist/components/SheetTerminal.js +21 -0
  90. package/dist/components/SheetText.d.ts +5 -0
  91. package/dist/components/SheetText.js +25 -0
  92. package/dist/components/SheetToast.d.ts +3 -0
  93. package/dist/components/SheetToast.js +24 -0
  94. package/dist/components/SheetWaiting.d.ts +7 -0
  95. package/dist/components/SheetWaiting.js +77 -0
  96. package/dist/hooks/use-native-platform.d.ts +10 -0
  97. package/dist/hooks/use-native-platform.js +47 -0
  98. package/dist/hooks/use-payment-sheet.d.ts +4 -0
  99. package/dist/hooks/use-payment-sheet.js +10 -0
  100. package/dist/hooks/use-sheet-motion.d.ts +7 -0
  101. package/dist/hooks/use-sheet-motion.js +62 -0
  102. package/dist/hooks/use-sheet-resize.d.ts +6 -0
  103. package/dist/hooks/use-sheet-resize.js +15 -0
  104. package/dist/hooks/use-sheet-theme.d.ts +4 -0
  105. package/dist/hooks/use-sheet-theme.js +12 -0
  106. package/dist/hooks/use-watched-payment.d.ts +6 -0
  107. package/dist/hooks/use-watched-payment.js +17 -0
  108. package/dist/index.d.ts +3 -0
  109. package/dist/index.js +2 -0
  110. package/dist/models/sheet.constants.d.ts +39 -0
  111. package/dist/models/sheet.constants.js +78 -0
  112. package/dist/models/sheet.enum.d.ts +16 -0
  113. package/dist/models/sheet.enum.js +18 -0
  114. package/dist/models/sheet.interface.d.ts +225 -0
  115. package/dist/models/sheet.interface.js +1 -0
  116. package/dist/models/sheet.utils.d.ts +43 -0
  117. package/dist/models/sheet.utils.js +132 -0
  118. package/dist/services/checkout.service.d.ts +7 -0
  119. package/dist/services/checkout.service.js +39 -0
  120. package/package.json +58 -4
@@ -0,0 +1,24 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { StyleSheet, View } from 'react-native';
3
+ import { useSheetTheme } from "../hooks/use-sheet-theme.js";
4
+ import { FigtreeEnum } from "../models/sheet.enum.js";
5
+ import { SheetText } from "./SheetText.js";
6
+ /** One short message at a time, over the top of the sheet. */
7
+ export function SheetToast({ message }) {
8
+ const { colors } = useSheetTheme();
9
+ if (!message)
10
+ return null;
11
+ return (_jsx(View, { pointerEvents: "none", accessibilityLiveRegion: "polite", accessibilityRole: "alert", style: [styles.toast, { backgroundColor: colors.ink }], children: _jsx(SheetText, { weight: FigtreeEnum.SEMI_BOLD, size: 13.5, color: colors.surface, style: styles.text, children: message }) }));
12
+ }
13
+ const styles = StyleSheet.create({
14
+ toast: {
15
+ position: 'absolute',
16
+ top: 56,
17
+ left: 18,
18
+ right: 18,
19
+ borderRadius: 12,
20
+ paddingHorizontal: 14,
21
+ paddingVertical: 11,
22
+ },
23
+ text: { textAlign: 'center' },
24
+ });
@@ -0,0 +1,7 @@
1
+ import type { SheetScreenProps } from '../models/sheet.interface.js';
2
+ /**
3
+ * Waiting for the payer to approve on their phone: what to do, the method
4
+ * and the clock, Resend once 30 seconds have passed, and another method.
5
+ * It moves on by itself.
6
+ */
7
+ export declare function SheetWaiting({ core }: SheetScreenProps): import("react").JSX.Element;
@@ -0,0 +1,77 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { Pressable, StyleSheet, View } from 'react-native';
4
+ import { useTranslations } from 'use-intl';
5
+ import { FLOW_TRAITS, URGENT_SECONDS, WAIT_SECONDS, } from "../checkout-core/models/checkout.constants.js";
6
+ import { CheckoutButtonVariantEnum } from "../checkout-core/models/checkout.enum.js";
7
+ import { formatClock, formatMoney, } from "../checkout-core/models/checkout.money.utils.js";
8
+ import { maskE164 } from "../checkout-core/models/checkout.phone.utils.js";
9
+ import { useSheetTheme } from "../hooks/use-sheet-theme.js";
10
+ import { FigtreeEnum } from "../models/sheet.enum.js";
11
+ import { resendLeftOf } from "../models/sheet.utils.js";
12
+ import { SheetButton } from "./SheetButton.js";
13
+ import { SheetLayout } from "./SheetLayout.js";
14
+ import { SheetRow } from "./SheetRow.js";
15
+ import { SheetSimulator } from "./SheetSimulator.js";
16
+ import { SheetText } from "./SheetText.js";
17
+ const NO_BREAK_SPACE = '\u00a0';
18
+ /**
19
+ * Waiting for the payer to approve on their phone: what to do, the method
20
+ * and the clock, Resend once 30 seconds have passed, and another method.
21
+ * It moves on by itself.
22
+ */
23
+ export function SheetWaiting({ core }) {
24
+ const t = useTranslations('checkout');
25
+ const { colors, brand } = useSheetTheme();
26
+ const { view, waitLeft, actions } = core;
27
+ const attempt = view.attempt;
28
+ // A payment code or a card needs nothing more from the payer: no prompt to resend.
29
+ const { prompt } = FLOW_TRAITS[attempt.flow];
30
+ /** The second of the wait the prompt was last sent at. */
31
+ const [sentAt, setSentAt] = useState(0);
32
+ const resendLeft = resendLeftOf(waitLeft, sentAt);
33
+ // The number never breaks across lines.
34
+ const phone = attempt.phone
35
+ ? maskE164(attempt.phone).replace(/ /g, NO_BREAK_SPACE)
36
+ : '';
37
+ return (_jsx(SheetLayout, { foot: _jsxs(_Fragment, { children: [prompt && (_jsx(SheetButton, { variant: CheckoutButtonVariantEnum.SECONDARY, label: resendLeft > 0
38
+ ? t('sheet.resend_in', { clock: formatClock(resendLeft) })
39
+ : t('resend'), disabled: resendLeft > 0, onPress: () => {
40
+ setSentAt(WAIT_SECONDS - waitLeft);
41
+ actions.resend();
42
+ } })), _jsx(Pressable, { onPress: actions.useAnother, accessibilityRole: "button", style: styles.link, children: _jsx(SheetText, { weight: FigtreeEnum.SEMI_BOLD, style: styles.center, children: t('use_another') }) })] }), children: _jsxs(View, { style: styles.waiting, children: [_jsxs(View, { style: styles.pulse, children: [_jsx(View, { style: [styles.halo, styles.outer, { backgroundColor: brand }] }), _jsx(View, { style: [styles.halo, styles.inner, { backgroundColor: brand }] }), _jsx(View, { testID: "icon-phone", style: [styles.phone, { borderColor: brand }], children: _jsx(View, { style: [styles.speaker, { backgroundColor: brand }] }) })] }), _jsx(SheetText, { weight: FigtreeEnum.EXTRA_BOLD, size: 21, accessibilityRole: "header", style: [styles.center, styles.title], children: prompt ? t('sheet.approve_title') : t('checking_title') }), _jsx(SheetText, { size: 14, color: colors.muted, style: styles.center, children: attempt.phone
43
+ ? prompt
44
+ ? t('sheet.approve_body', {
45
+ method: attempt.methodName,
46
+ phone,
47
+ })
48
+ : `${t('checking_with', { method: attempt.methodName })} ${phone}`
49
+ : t('checking_card', { method: attempt.methodName }) }), _jsxs(View, { style: [styles.rows, { borderColor: colors.line }], children: [_jsx(SheetRow, { label: attempt.methodName, children: formatMoney(view.amount, view.currency) }), _jsx(SheetRow, { label: t('sheet.expires_in'), urgent: waitLeft <= URGENT_SECONDS, children: formatClock(waitLeft) })] }), attempt.simulated && _jsx(SheetSimulator, { core: core })] }) }));
50
+ }
51
+ const styles = StyleSheet.create({
52
+ waiting: { paddingHorizontal: 18, paddingTop: 30 },
53
+ pulse: {
54
+ alignSelf: 'center',
55
+ width: 128,
56
+ height: 128,
57
+ alignItems: 'center',
58
+ justifyContent: 'center',
59
+ },
60
+ halo: { position: 'absolute' },
61
+ outer: { width: 128, height: 128, borderRadius: 64, opacity: 0.06 },
62
+ inner: { width: 96, height: 96, borderRadius: 48, opacity: 0.12 },
63
+ phone: {
64
+ width: 24,
65
+ height: 38,
66
+ borderWidth: 2.5,
67
+ borderRadius: 6,
68
+ alignItems: 'center',
69
+ justifyContent: 'flex-end',
70
+ paddingBottom: 4,
71
+ },
72
+ speaker: { width: 6, height: 2.5, borderRadius: 1.25 },
73
+ title: { marginTop: 22, marginBottom: 8, letterSpacing: -0.4 },
74
+ center: { textAlign: 'center' },
75
+ rows: { borderTopWidth: 1, marginTop: 22 },
76
+ link: { minHeight: 40, justifyContent: 'center' },
77
+ });
@@ -0,0 +1,10 @@
1
+ import type { RefObject } from 'react';
2
+ import type { TextInputInstance } from 'react-native';
3
+ import type { NativePlatform } from '../models/sheet.interface.js';
4
+ /**
5
+ * What only the phone does for the checkout core. Leaving for the app is
6
+ * closing the sheet: `presentPayment` resolves, nothing opens the return URL.
7
+ * The card fields page talks through its WebView (`cardFields`). One stable
8
+ * object for the sheet's life.
9
+ */
10
+ export declare function useNativePlatform(onLeave: () => void, phoneField: RefObject<TextInputInstance | null>): NativePlatform;
@@ -0,0 +1,47 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { AppState, Share } from 'react-native';
3
+ import { cardFieldsSubmit } from "../models/sheet.utils.js";
4
+ /**
5
+ * What only the phone does for the checkout core. Leaving for the app is
6
+ * closing the sheet: `presentPayment` resolves, nothing opens the return URL.
7
+ * The card fields page talks through its WebView (`cardFields`). One stable
8
+ * object for the sheet's life.
9
+ */
10
+ export function useNativePlatform(onLeave, phoneField) {
11
+ const leave = useRef(onLeave);
12
+ useEffect(() => {
13
+ leave.current = onLeave;
14
+ }, [onLeave]);
15
+ const cardPage = useRef(null);
16
+ const [cardListeners] = useState(() => new Set());
17
+ const [platform] = useState(() => ({
18
+ onReturn: (listener) => {
19
+ const subscription = AppState.addEventListener('change', (state) => {
20
+ if (state === 'active')
21
+ listener();
22
+ });
23
+ return () => subscription.remove();
24
+ },
25
+ // No clipboard in React Native itself: the share sheet offers Copy.
26
+ copyText: (text) => {
27
+ void Share.share({ message: text }).catch(() => undefined);
28
+ },
29
+ openUrl: () => leave.current(),
30
+ onCardMessage: (listener) => {
31
+ cardListeners.add(listener);
32
+ return () => void cardListeners.delete(listener);
33
+ },
34
+ // Pay is pressed on the form, where a picked card always shows its page.
35
+ submitCard: () => cardPage.current.injectJavaScript(cardFieldsSubmit()),
36
+ saveReceipt: (fileName, text) => {
37
+ void Share.share({ title: fileName, message: text }).catch(() => undefined);
38
+ },
39
+ // A wrong number on Pay: the keyboard comes up on it.
40
+ onPhoneRejected: () => phoneField.current?.focus(),
41
+ }));
42
+ const [cardFields] = useState(() => ({
43
+ page: cardPage,
44
+ receive: (message) => cardListeners.forEach((listener) => listener(message)),
45
+ }));
46
+ return { platform, cardFields };
47
+ }
@@ -0,0 +1,4 @@
1
+ import type { PaymentSheet } from '../models/sheet.interface.js';
2
+ export declare const PaymentSheetContext: import("react").Context<PaymentSheet | null>;
3
+ /** `presentPayment`, from the `BrissotoPayProvider` around the app. */
4
+ export declare function usePaymentSheet(): PaymentSheet;
@@ -0,0 +1,10 @@
1
+ import { createContext, use } from 'react';
2
+ export const PaymentSheetContext = createContext(null);
3
+ /** `presentPayment`, from the `BrissotoPayProvider` around the app. */
4
+ export function usePaymentSheet() {
5
+ const sheet = use(PaymentSheetContext);
6
+ if (!sheet) {
7
+ throw new Error('usePaymentSheet needs a BrissotoPayProvider around the app.');
8
+ }
9
+ return sheet;
10
+ }
@@ -0,0 +1,7 @@
1
+ import type { SheetMotion } from '../models/sheet.interface.js';
2
+ /**
3
+ * The bottom sheet's moves, in plain React Native: it slides up from below
4
+ * the screen, follows a finger dragging its top down, springs back or
5
+ * `onSwipe`s when let go, and slides away once `open` turns false.
6
+ */
7
+ export declare function useSheetMotion(open: boolean, onSwipe: () => void): SheetMotion;
@@ -0,0 +1,62 @@
1
+ import { useEffect, useMemo, useRef, useState } from 'react';
2
+ import { Animated, Easing, PanResponder, useWindowDimensions, } from 'react-native';
3
+ import { SHEET_DIM_OPACITY, SHEET_SLIDE_MS, SHEET_TOP_GAP, } from "../models/sheet.constants.js";
4
+ import { sheetSwipeCloses } from "../models/sheet.utils.js";
5
+ /**
6
+ * The bottom sheet's moves, in plain React Native: it slides up from below
7
+ * the screen, follows a finger dragging its top down, springs back or
8
+ * `onSwipe`s when let go, and slides away once `open` turns false.
9
+ */
10
+ export function useSheetMotion(open, onSwipe) {
11
+ const { height } = useWindowDimensions();
12
+ const [slide] = useState(() => new Animated.Value(height));
13
+ const [drag] = useState(() => new Animated.Value(0));
14
+ const [shown, setShown] = useState(open);
15
+ const swiped = useRef(onSwipe);
16
+ useEffect(() => {
17
+ swiped.current = onSwipe;
18
+ }, [onSwipe]);
19
+ useEffect(() => {
20
+ Animated.timing(slide, {
21
+ toValue: open ? 0 : height,
22
+ duration: SHEET_SLIDE_MS,
23
+ easing: Easing.out(Easing.cubic),
24
+ useNativeDriver: true,
25
+ }).start(() => {
26
+ if (!open)
27
+ setShown(false);
28
+ });
29
+ }, [open, height, slide]);
30
+ const [dragHandlers] = useState(() => {
31
+ const settle = () => Animated.spring(drag, {
32
+ toValue: 0,
33
+ bounciness: 0,
34
+ useNativeDriver: true,
35
+ }).start();
36
+ return PanResponder.create({
37
+ // The top holds only close, which takes its own taps.
38
+ onStartShouldSetPanResponder: () => true,
39
+ onPanResponderMove: (_event, { dy }) => drag.setValue(Math.max(0, dy)),
40
+ onPanResponderRelease: (_event, { dy, vy }) => {
41
+ // Closing asks first while a prompt waits: the sheet comes back up.
42
+ if (sheetSwipeCloses(dy, vy))
43
+ swiped.current();
44
+ settle();
45
+ },
46
+ onPanResponderTerminate: settle,
47
+ }).panHandlers;
48
+ });
49
+ const [translateY] = useState(() => Animated.add(slide, drag));
50
+ const dim = useMemo(() => translateY.interpolate({
51
+ inputRange: [0, height],
52
+ outputRange: [SHEET_DIM_OPACITY, 0],
53
+ extrapolate: 'clamp',
54
+ }), [translateY, height]);
55
+ return {
56
+ shown,
57
+ translateY,
58
+ dim,
59
+ dragHandlers,
60
+ topGap: height * SHEET_TOP_GAP,
61
+ };
62
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Eases the sheet's height when what it shows changes `shape` (another
3
+ * screen, tab, method, the card fields' page): the next layout animates,
4
+ * on iOS and Android alike. The first one does not: the sheet slides up.
5
+ */
6
+ export declare function useSheetResize(shape: string): void;
@@ -0,0 +1,15 @@
1
+ import { useState } from 'react';
2
+ import { LayoutAnimation } from 'react-native';
3
+ import { SHEET_RESIZE } from "../models/sheet.constants.js";
4
+ /**
5
+ * Eases the sheet's height when what it shows changes `shape` (another
6
+ * screen, tab, method, the card fields' page): the next layout animates,
7
+ * on iOS and Android alike. The first one does not: the sheet slides up.
8
+ */
9
+ export function useSheetResize(shape) {
10
+ const [last, setLast] = useState(shape);
11
+ if (last !== shape) {
12
+ setLast(shape);
13
+ LayoutAnimation.configureNext(SHEET_RESIZE);
14
+ }
15
+ }
@@ -0,0 +1,4 @@
1
+ import type { SheetTheme } from '../models/sheet.interface.js';
2
+ export declare const SheetThemeContext: import("react").Context<SheetTheme>;
3
+ /** The open sheet's colours. */
4
+ export declare function useSheetTheme(): SheetTheme;
@@ -0,0 +1,12 @@
1
+ import { createContext, use } from 'react';
2
+ import { CHECKOUT_COLORS } from "../checkout-core/models/checkout.constants.js";
3
+ import { CheckoutThemeEnum } from "../checkout-core/models/checkout.enum.js";
4
+ export const SheetThemeContext = createContext({
5
+ colors: CHECKOUT_COLORS[CheckoutThemeEnum.LIGHT],
6
+ brand: CHECKOUT_COLORS[CheckoutThemeEnum.LIGHT].ink,
7
+ dark: false,
8
+ });
9
+ /** The open sheet's colours. */
10
+ export function useSheetTheme() {
11
+ return use(SheetThemeContext);
12
+ }
@@ -0,0 +1,6 @@
1
+ import type { CheckoutCalls, WatchedPayment } from '../models/sheet.interface.js';
2
+ /**
3
+ * One payment, live, while `paymentId` is set. Once it is cleared (the sheet
4
+ * closing) the last answer stays, so the sheet slides away unchanged.
5
+ */
6
+ export declare function useWatchedPayment(calls: CheckoutCalls, paymentId: string | null): WatchedPayment;
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react';
2
+ /**
3
+ * One payment, live, while `paymentId` is set. Once it is cleared (the sheet
4
+ * closing) the last answer stays, so the sheet slides away unchanged.
5
+ */
6
+ export function useWatchedPayment(calls, paymentId) {
7
+ const [watched, setWatched] = useState({
8
+ view: undefined,
9
+ failed: false,
10
+ });
11
+ useEffect(() => {
12
+ if (!paymentId)
13
+ return undefined;
14
+ return calls.watch(paymentId, (view) => setWatched({ view, failed: false }), () => setWatched((previous) => ({ ...previous, failed: true })));
15
+ }, [calls, paymentId]);
16
+ return watched;
17
+ }
@@ -0,0 +1,3 @@
1
+ export { BrissotoPayProvider } from './components/BrissotoPayProvider.js';
2
+ export { usePaymentSheet } from './hooks/use-payment-sheet.js';
3
+ export type { BrissotoPayProviderProps, PaymentSheet, PaymentSheetError, PaymentSheetResult, PaymentSheetStatus, PresentPaymentOptions, } from './models/sheet.interface.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { BrissotoPayProvider } from "./components/BrissotoPayProvider.js";
2
+ export { usePaymentSheet } from "./hooks/use-payment-sheet.js";
@@ -0,0 +1,39 @@
1
+ import type { LayoutAnimationConfig } from 'react-native';
2
+ import en from '../checkout-core/messages/en.js';
3
+ import { LangEnum, ProviderLogoEnum } from '../checkout-core/models/domain.enum.js';
4
+ import { FigtreeEnum } from './sheet.enum.js';
5
+ /** The production backend: Live and Test payments alike. */
6
+ export declare const DEFAULT_URL = "https://api-pay.brissoto.com";
7
+ /** The public Convex functions the web checkout calls, by path. */
8
+ export declare const CHECKOUT_FUNCTIONS: {
9
+ get: string;
10
+ pay: string;
11
+ payWithCode: string;
12
+ checkNow: string;
13
+ open: string;
14
+ cancel: string;
15
+ resend: string;
16
+ simulate: string;
17
+ };
18
+ /** Figtree ships inside the package: `expo-font` loads it when a sheet opens. */
19
+ export declare const FIGTREE_FILES: Record<FigtreeEnum, number>;
20
+ /** The sheet's timezone for dates, as the web checkout's. */
21
+ export declare const TIME_ZONE = "Africa/Douala";
22
+ /** The payer copy the web checkout shows, by language. */
23
+ export declare const MESSAGES: Record<LangEnum, {
24
+ checkout: typeof en;
25
+ }>;
26
+ /** Brand tiles, the web's `public/logo/` PNGs bundled with the package. */
27
+ export declare const PROVIDER_LOGOS: Record<ProviderLogoEnum, number>;
28
+ /** At its tallest, the sheet leaves this share of the screen above it, clear of the status bar. */
29
+ export declare const SHEET_TOP_GAP = 0.1;
30
+ /** How dark the app gets behind the sheet. */
31
+ export declare const SHEET_DIM_OPACITY = 0.4;
32
+ /** How long the sheet takes to slide up or away, in ms. */
33
+ export declare const SHEET_SLIDE_MS = 280;
34
+ /** Points down that close the sheet when the finger lets go. */
35
+ export declare const SHEET_SWIPE_DISTANCE = 120;
36
+ /** A flick down this fast (points per ms) closes it, however short. */
37
+ export declare const SHEET_FLICK_SPEED = 0.8;
38
+ /** How the sheet's height eases from one screen to the next. */
39
+ export declare const SHEET_RESIZE: LayoutAnimationConfig;
@@ -0,0 +1,78 @@
1
+ import figtreeBold from '../../assets/fonts/Figtree-Bold.ttf';
2
+ import figtreeExtraBold from '../../assets/fonts/Figtree-ExtraBold.ttf';
3
+ import figtreeMedium from '../../assets/fonts/Figtree-Medium.ttf';
4
+ import figtreeRegular from '../../assets/fonts/Figtree-Regular.ttf';
5
+ import figtreeSemiBold from '../../assets/fonts/Figtree-SemiBold.ttf';
6
+ import logoApplePay from '../../assets/logos/apple-pay.png';
7
+ import logoCard from '../../assets/logos/card.png';
8
+ import logoGooglePay from '../../assets/logos/google-pay.png';
9
+ import logoMastercard from '../../assets/logos/mastercard.png';
10
+ import logoMixx from '../../assets/logos/mixx.png';
11
+ import logoMoov from '../../assets/logos/moov.png';
12
+ import logoMtn from '../../assets/logos/mtn.png';
13
+ import logoOrange from '../../assets/logos/orange.png';
14
+ import logoPaypal from '../../assets/logos/paypal.png';
15
+ import logoVisa from '../../assets/logos/visa.png';
16
+ import logoWave from '../../assets/logos/wave.png';
17
+ import { LayoutAnimation } from 'react-native';
18
+ import en from "../checkout-core/messages/en.js";
19
+ import fr from "../checkout-core/messages/fr.js";
20
+ import { LangEnum, ProviderLogoEnum, } from "../checkout-core/models/domain.enum.js";
21
+ import { FigtreeEnum } from "./sheet.enum.js";
22
+ /** The production backend: Live and Test payments alike. */
23
+ export const DEFAULT_URL = 'https://api-pay.brissoto.com';
24
+ /** The public Convex functions the web checkout calls, by path. */
25
+ export const CHECKOUT_FUNCTIONS = {
26
+ get: 'checkout/queries:get',
27
+ pay: 'checkout/mutations:pay',
28
+ payWithCode: 'checkout/actions:payWithCode',
29
+ checkNow: 'checkout/mutations:checkNow',
30
+ open: 'checkout/mutations:open',
31
+ cancel: 'checkout/mutations:cancel',
32
+ resend: 'checkout/mutations:resend',
33
+ simulate: 'simulator/mutations:decide',
34
+ };
35
+ /** Figtree ships inside the package: `expo-font` loads it when a sheet opens. */
36
+ export const FIGTREE_FILES = {
37
+ [FigtreeEnum.REGULAR]: figtreeRegular,
38
+ [FigtreeEnum.MEDIUM]: figtreeMedium,
39
+ [FigtreeEnum.SEMI_BOLD]: figtreeSemiBold,
40
+ [FigtreeEnum.BOLD]: figtreeBold,
41
+ [FigtreeEnum.EXTRA_BOLD]: figtreeExtraBold,
42
+ };
43
+ /** The sheet's timezone for dates, as the web checkout's. */
44
+ export const TIME_ZONE = 'Africa/Douala';
45
+ /** The payer copy the web checkout shows, by language. */
46
+ export const MESSAGES = {
47
+ [LangEnum.EN]: { checkout: en },
48
+ [LangEnum.FR]: { checkout: fr },
49
+ };
50
+ /** Brand tiles, the web's `public/logo/` PNGs bundled with the package. */
51
+ export const PROVIDER_LOGOS = {
52
+ [ProviderLogoEnum.ORANGE]: logoOrange,
53
+ [ProviderLogoEnum.MTN]: logoMtn,
54
+ [ProviderLogoEnum.MOOV]: logoMoov,
55
+ [ProviderLogoEnum.WAVE]: logoWave,
56
+ [ProviderLogoEnum.MIXX]: logoMixx,
57
+ [ProviderLogoEnum.VISA]: logoVisa,
58
+ [ProviderLogoEnum.MASTERCARD]: logoMastercard,
59
+ [ProviderLogoEnum.PAYPAL]: logoPaypal,
60
+ [ProviderLogoEnum.CARD]: logoCard,
61
+ [ProviderLogoEnum.APPLE_PAY]: logoApplePay,
62
+ [ProviderLogoEnum.GOOGLE_PAY]: logoGooglePay,
63
+ };
64
+ /** At its tallest, the sheet leaves this share of the screen above it, clear of the status bar. */
65
+ export const SHEET_TOP_GAP = 0.1;
66
+ /** How dark the app gets behind the sheet. */
67
+ export const SHEET_DIM_OPACITY = 0.4;
68
+ /** How long the sheet takes to slide up or away, in ms. */
69
+ export const SHEET_SLIDE_MS = 280;
70
+ /** Points down that close the sheet when the finger lets go. */
71
+ export const SHEET_SWIPE_DISTANCE = 120;
72
+ /** A flick down this fast (points per ms) closes it, however short. */
73
+ export const SHEET_FLICK_SPEED = 0.8;
74
+ /** How the sheet's height eases from one screen to the next. */
75
+ export const SHEET_RESIZE = {
76
+ duration: 220,
77
+ update: { type: LayoutAnimation.Types.easeInEaseOut },
78
+ };
@@ -0,0 +1,16 @@
1
+ /** Figtree's weights the sheet uses. Values are the font family names `expo-font` registers. */
2
+ export declare enum FigtreeEnum {
3
+ REGULAR = "Figtree-Regular",
4
+ MEDIUM = "Figtree-Medium",
5
+ SEMI_BOLD = "Figtree-SemiBold",
6
+ BOLD = "Figtree-Bold",
7
+ EXTRA_BOLD = "Figtree-ExtraBold"
8
+ }
9
+ /** The signs the sheet draws, in a disc. */
10
+ export declare enum SheetIconEnum {
11
+ BAN = "ban",
12
+ CLOCK = "clock",
13
+ LOCK = "lock",
14
+ CROSS = "cross",
15
+ CHECK = "check"
16
+ }
@@ -0,0 +1,18 @@
1
+ /** Figtree's weights the sheet uses. Values are the font family names `expo-font` registers. */
2
+ export var FigtreeEnum;
3
+ (function (FigtreeEnum) {
4
+ FigtreeEnum["REGULAR"] = "Figtree-Regular";
5
+ FigtreeEnum["MEDIUM"] = "Figtree-Medium";
6
+ FigtreeEnum["SEMI_BOLD"] = "Figtree-SemiBold";
7
+ FigtreeEnum["BOLD"] = "Figtree-Bold";
8
+ FigtreeEnum["EXTRA_BOLD"] = "Figtree-ExtraBold";
9
+ })(FigtreeEnum || (FigtreeEnum = {}));
10
+ /** The signs the sheet draws, in a disc. */
11
+ export var SheetIconEnum;
12
+ (function (SheetIconEnum) {
13
+ SheetIconEnum["BAN"] = "ban";
14
+ SheetIconEnum["CLOCK"] = "clock";
15
+ SheetIconEnum["LOCK"] = "lock";
16
+ SheetIconEnum["CROSS"] = "cross";
17
+ SheetIconEnum["CHECK"] = "check";
18
+ })(SheetIconEnum || (SheetIconEnum = {}));