@reevit/react 0.4.8 → 0.4.9

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/dist/index.d.mts CHANGED
@@ -97,22 +97,16 @@ interface PaymentError {
97
97
  details?: Record<string, unknown>;
98
98
  }
99
99
  interface ReevitTheme {
100
- /** Primary brand color */
100
+ /** Primary color (main text, headings, important elements) */
101
101
  primaryColor?: string;
102
- /** Primary text color on brand surfaces */
102
+ /** Primary foreground color (sub text, descriptions, muted elements) */
103
103
  primaryForegroundColor?: string;
104
- /** Background color */
104
+ /** Background color (applies to entire checkout: header, body, footer) */
105
105
  backgroundColor?: string;
106
- /** Surface color for cards/panels */
107
- surfaceColor?: string;
108
- /** Text color */
109
- textColor?: string;
110
- /** Muted text color */
111
- mutedTextColor?: string;
106
+ /** Border color (borders, dividers) */
107
+ borderColor?: string;
112
108
  /** Border radius for inputs and buttons */
113
109
  borderRadius?: string;
114
- /** Font family to use */
115
- fontFamily?: string;
116
110
  /** Whether to use dark mode */
117
111
  darkMode?: boolean;
118
112
  /** Custom logo URL to display in checkout header */
@@ -127,12 +121,29 @@ interface ReevitTheme {
127
121
  pspSelectorBorderColor?: string;
128
122
  /** Use border-only style for PSP selector (no filled background) */
129
123
  pspSelectorUseBorder?: boolean;
124
+ /** Selected PSP background color */
125
+ selectedBackgroundColor?: string;
126
+ /** Selected PSP primary text color */
127
+ selectedTextColor?: string;
128
+ /** Selected PSP description/muted text color */
129
+ selectedDescriptionColor?: string;
130
+ /** Selected PSP border color */
131
+ selectedBorderColor?: string;
130
132
  }
131
133
  interface CheckoutProviderOption {
132
134
  provider: string;
133
135
  name: string;
134
136
  methods: PaymentMethod[];
135
137
  countries?: string[];
138
+ /** Brand colors for selected state styling */
139
+ branding?: {
140
+ /** Background color when selected */
141
+ backgroundColor?: string;
142
+ /** Primary/accent color */
143
+ primaryColor?: string;
144
+ /** Text color on primary background */
145
+ primaryForegroundColor?: string;
146
+ };
136
147
  }
137
148
  interface MobileMoneyFormData {
138
149
  phone: string;
@@ -159,7 +170,7 @@ interface PaymentIntent {
159
170
  /** Currency code */
160
171
  currency: string;
161
172
  /** Payment status */
162
- status: 'pending' | 'processing' | 'succeeded' | 'failed' | 'cancelled';
173
+ status: 'pending' | 'requires_action' | 'processing' | 'succeeded' | 'failed' | 'canceled' | 'cancelled';
163
174
  /** Recommended PSP based on routing rules */
164
175
  recommendedPsp: 'paystack' | 'hubtel' | 'flutterwave' | 'monnify' | 'mpesa' | 'stripe';
165
176
  /** Available payment methods for this intent */
@@ -200,8 +211,17 @@ interface PaymentMethodSelectorProps {
200
211
  provider?: string;
201
212
  layout?: 'grid' | 'list';
202
213
  showLabel?: boolean;
214
+ /** Country code for dynamic logos (e.g., 'GH', 'NG', 'KE') */
215
+ country?: string;
216
+ /** Selected theme colors for method items */
217
+ selectedTheme?: {
218
+ backgroundColor?: string;
219
+ textColor?: string;
220
+ descriptionColor?: string;
221
+ borderColor?: string;
222
+ };
203
223
  }
204
- declare function PaymentMethodSelector({ methods, selectedMethod, onSelect, disabled, provider, layout, showLabel, }: PaymentMethodSelectorProps): react_jsx_runtime.JSX.Element;
224
+ declare function PaymentMethodSelector({ methods, selectedMethod, onSelect, disabled, provider, layout, showLabel, country, selectedTheme, }: PaymentMethodSelectorProps): react_jsx_runtime.JSX.Element;
205
225
 
206
226
  interface MobileMoneyFormProps {
207
227
  onSubmit: (data: MobileMoneyFormData) => void;
@@ -595,6 +615,11 @@ interface PaymentIntentResponse {
595
615
  status: string;
596
616
  client_secret: string;
597
617
  psp_public_key?: string;
618
+ psp_credentials?: {
619
+ merchantAccount?: string | number;
620
+ basicAuth?: string;
621
+ [key: string]: unknown;
622
+ };
598
623
  amount: number;
599
624
  currency: string;
600
625
  fee_amount: number;
package/dist/index.d.ts CHANGED
@@ -97,22 +97,16 @@ interface PaymentError {
97
97
  details?: Record<string, unknown>;
98
98
  }
99
99
  interface ReevitTheme {
100
- /** Primary brand color */
100
+ /** Primary color (main text, headings, important elements) */
101
101
  primaryColor?: string;
102
- /** Primary text color on brand surfaces */
102
+ /** Primary foreground color (sub text, descriptions, muted elements) */
103
103
  primaryForegroundColor?: string;
104
- /** Background color */
104
+ /** Background color (applies to entire checkout: header, body, footer) */
105
105
  backgroundColor?: string;
106
- /** Surface color for cards/panels */
107
- surfaceColor?: string;
108
- /** Text color */
109
- textColor?: string;
110
- /** Muted text color */
111
- mutedTextColor?: string;
106
+ /** Border color (borders, dividers) */
107
+ borderColor?: string;
112
108
  /** Border radius for inputs and buttons */
113
109
  borderRadius?: string;
114
- /** Font family to use */
115
- fontFamily?: string;
116
110
  /** Whether to use dark mode */
117
111
  darkMode?: boolean;
118
112
  /** Custom logo URL to display in checkout header */
@@ -127,12 +121,29 @@ interface ReevitTheme {
127
121
  pspSelectorBorderColor?: string;
128
122
  /** Use border-only style for PSP selector (no filled background) */
129
123
  pspSelectorUseBorder?: boolean;
124
+ /** Selected PSP background color */
125
+ selectedBackgroundColor?: string;
126
+ /** Selected PSP primary text color */
127
+ selectedTextColor?: string;
128
+ /** Selected PSP description/muted text color */
129
+ selectedDescriptionColor?: string;
130
+ /** Selected PSP border color */
131
+ selectedBorderColor?: string;
130
132
  }
131
133
  interface CheckoutProviderOption {
132
134
  provider: string;
133
135
  name: string;
134
136
  methods: PaymentMethod[];
135
137
  countries?: string[];
138
+ /** Brand colors for selected state styling */
139
+ branding?: {
140
+ /** Background color when selected */
141
+ backgroundColor?: string;
142
+ /** Primary/accent color */
143
+ primaryColor?: string;
144
+ /** Text color on primary background */
145
+ primaryForegroundColor?: string;
146
+ };
136
147
  }
137
148
  interface MobileMoneyFormData {
138
149
  phone: string;
@@ -159,7 +170,7 @@ interface PaymentIntent {
159
170
  /** Currency code */
160
171
  currency: string;
161
172
  /** Payment status */
162
- status: 'pending' | 'processing' | 'succeeded' | 'failed' | 'cancelled';
173
+ status: 'pending' | 'requires_action' | 'processing' | 'succeeded' | 'failed' | 'canceled' | 'cancelled';
163
174
  /** Recommended PSP based on routing rules */
164
175
  recommendedPsp: 'paystack' | 'hubtel' | 'flutterwave' | 'monnify' | 'mpesa' | 'stripe';
165
176
  /** Available payment methods for this intent */
@@ -200,8 +211,17 @@ interface PaymentMethodSelectorProps {
200
211
  provider?: string;
201
212
  layout?: 'grid' | 'list';
202
213
  showLabel?: boolean;
214
+ /** Country code for dynamic logos (e.g., 'GH', 'NG', 'KE') */
215
+ country?: string;
216
+ /** Selected theme colors for method items */
217
+ selectedTheme?: {
218
+ backgroundColor?: string;
219
+ textColor?: string;
220
+ descriptionColor?: string;
221
+ borderColor?: string;
222
+ };
203
223
  }
204
- declare function PaymentMethodSelector({ methods, selectedMethod, onSelect, disabled, provider, layout, showLabel, }: PaymentMethodSelectorProps): react_jsx_runtime.JSX.Element;
224
+ declare function PaymentMethodSelector({ methods, selectedMethod, onSelect, disabled, provider, layout, showLabel, country, selectedTheme, }: PaymentMethodSelectorProps): react_jsx_runtime.JSX.Element;
205
225
 
206
226
  interface MobileMoneyFormProps {
207
227
  onSubmit: (data: MobileMoneyFormData) => void;
@@ -595,6 +615,11 @@ interface PaymentIntentResponse {
595
615
  status: string;
596
616
  client_secret: string;
597
617
  psp_public_key?: string;
618
+ psp_credentials?: {
619
+ merchantAccount?: string | number;
620
+ basicAuth?: string;
621
+ [key: string]: unknown;
622
+ };
598
623
  amount: number;
599
624
  currency: string;
600
625
  fee_amount: number;
package/dist/index.js CHANGED
@@ -62,61 +62,45 @@ function detectNetwork(phone) {
62
62
  }
63
63
  return null;
64
64
  }
65
- function createThemeVariables(theme) {
66
- const variables = {};
67
- if (theme.primaryColor) {
68
- variables["--reevit-primary"] = theme.primaryColor;
69
- if (theme.primaryForegroundColor) {
70
- variables["--reevit-primary-foreground"] = theme.primaryForegroundColor;
71
- } else {
72
- const contrast = getContrastingColor(theme.primaryColor);
73
- if (contrast) {
74
- variables["--reevit-primary-foreground"] = contrast;
75
- }
76
- }
77
- }
78
- if (theme.backgroundColor) {
79
- variables["--reevit-background"] = theme.backgroundColor;
80
- }
81
- if (theme.surfaceColor) {
82
- variables["--reevit-surface"] = theme.surfaceColor;
83
- }
84
- if (theme.textColor) {
85
- variables["--reevit-text"] = theme.textColor;
86
- }
87
- if (theme.mutedTextColor) {
88
- variables["--reevit-text-secondary"] = theme.mutedTextColor;
89
- }
90
- if (theme.borderRadius) {
91
- variables["--reevit-radius"] = theme.borderRadius;
92
- variables["--reevit-radius-sm"] = theme.borderRadius;
93
- variables["--reevit-radius-lg"] = theme.borderRadius;
94
- }
95
- if (theme.fontFamily) {
96
- variables["--reevit-font"] = theme.fontFamily;
97
- }
98
- return variables;
65
+ function cn(...classes) {
66
+ return classes.filter(Boolean).join(" ");
99
67
  }
100
- function getContrastingColor(color) {
101
- const hex = color.trim();
102
- if (!hex.startsWith("#")) {
103
- return null;
104
- }
105
- const normalized = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
106
- if (normalized.length !== 7) {
107
- return null;
68
+ function getCountryFromCurrency(currency) {
69
+ const currencyToCountry = {
70
+ GHS: "GH",
71
+ NGN: "NG",
72
+ KES: "KE",
73
+ ZAR: "ZA",
74
+ USD: "US",
75
+ GBP: "GB",
76
+ EUR: "EU"
77
+ };
78
+ return currencyToCountry[currency.toUpperCase()] || "GH";
79
+ }
80
+ function getMethodLogos(country, method) {
81
+ const c = country.toUpperCase();
82
+ const LOGOS = {
83
+ visa: "https://js.stripe.com/v3/fingerprinted/img/visa-729c05c240c4bdb47b03ac81d9945bfe.svg",
84
+ mastercard: "https://js.stripe.com/v3/fingerprinted/img/mastercard-4d8844094130711885b5e41b28c9848f.svg",
85
+ apple_pay: "https://js.stripe.com/v3/fingerprinted/img/apple_pay_mark-ea40d9a0f83ff6c94c3aa5c2c1ba4427.svg",
86
+ google_pay: "https://js.stripe.com/v3/fingerprinted/img/google_pay_mark-ed0c5a85e00a6e95f57a3c89e9d2a69c.svg",
87
+ mtn: "https://play-lh.googleusercontent.com/WdLBv6Ck6Xk4VJQvPxODXXjLNmxEGHDnXML_TVqWOBBzXpWLV1K3xXlStCfFLrl0Tw=w240-h480-rw",
88
+ vodafone: "https://play-lh.googleusercontent.com/cTpsmMl_ZXKvPLKWwCvC0VaKgT1ISyH0fNDgVbXHMGJl4PYvGMnlFFe8Kj3vTqz0Xg=w240-h480-rw",
89
+ airtel: "https://play-lh.googleusercontent.com/Mh2OxhKPKMfxCn2Y7J3gD3TLvkvOeFXwPLLGqrDHD5qJ5le_ph7Y6PmfwwZKJMZWcYU=w240-h480-rw",
90
+ mpesa: "https://play-lh.googleusercontent.com/2wd-PssHqg1Xv0HnKzH7ecFfozXo_vr5M-Hf7k7X7kqxMGqj5PmKWnFhTqCYXCPCAYE=w240-h480-rw"
91
+ };
92
+ if (method === "card") {
93
+ return [LOGOS.visa, LOGOS.mastercard];
108
94
  }
109
- const r = parseInt(normalized.slice(1, 3), 16);
110
- const g = parseInt(normalized.slice(3, 5), 16);
111
- const b = parseInt(normalized.slice(5, 7), 16);
112
- if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) {
113
- return null;
95
+ if (method === "apple_pay") return [LOGOS.apple_pay];
96
+ if (method === "google_pay") return [LOGOS.google_pay];
97
+ if (method === "mobile_money") {
98
+ if (c === "GH") return [LOGOS.mtn, LOGOS.vodafone, LOGOS.airtel];
99
+ if (c === "KE") return [LOGOS.mpesa, LOGOS.airtel];
100
+ if (c === "NG") return [LOGOS.mtn, LOGOS.airtel];
101
+ return [LOGOS.mtn];
114
102
  }
115
- const brightness = (r * 299 + g * 587 + b * 114) / 1e3;
116
- return brightness >= 140 ? "#0b1120" : "#ffffff";
117
- }
118
- function cn(...classes) {
119
- return classes.filter(Boolean).join(" ");
103
+ return [];
120
104
  }
121
105
 
122
106
  // src/api/client.ts
@@ -394,6 +378,10 @@ function normalizeBranding(branding) {
394
378
  setIf("pspSelectorTextColor", getString(raw.pspSelectorTextColor ?? raw.psp_selector_text_color));
395
379
  setIf("pspSelectorBorderColor", getString(raw.pspSelectorBorderColor ?? raw.psp_selector_border_color));
396
380
  setIf("pspSelectorUseBorder", getBoolean(raw.pspSelectorUseBorder ?? raw.psp_selector_use_border));
381
+ setIf("selectedBackgroundColor", getString(raw.selectedBackgroundColor ?? raw.selected_background_color));
382
+ setIf("selectedTextColor", getString(raw.selectedTextColor ?? raw.selected_text_color));
383
+ setIf("selectedDescriptionColor", getString(raw.selectedDescriptionColor ?? raw.selected_description_color));
384
+ setIf("selectedBorderColor", getString(raw.selectedBorderColor ?? raw.selected_border_color));
397
385
  return theme;
398
386
  }
399
387
  function mapToPaymentIntent(response, config) {
@@ -401,6 +389,7 @@ function mapToPaymentIntent(response, config) {
401
389
  id: response.id,
402
390
  clientSecret: response.client_secret,
403
391
  pspPublicKey: response.psp_public_key,
392
+ pspCredentials: response.psp_credentials,
404
393
  amount: response.amount,
405
394
  currency: response.currency,
406
395
  status: response.status,
@@ -700,59 +689,90 @@ function PaymentMethodSelector({
700
689
  disabled = false,
701
690
  provider,
702
691
  layout = "list",
703
- showLabel = true
692
+ showLabel = true,
693
+ country = "GH",
694
+ selectedTheme
704
695
  }) {
705
696
  const getMethodLabel = (method, psp) => {
706
697
  const config = methodConfig[method];
707
698
  return config.label;
708
699
  };
709
- const getMethodDescription = (method, psp) => {
710
- const config = methodConfig[method];
711
- if (psp?.toLowerCase().includes("hubtel")) {
712
- return config.description;
700
+ const getMethodDescription = (method, psp, countryCode) => {
701
+ const c = (country).toUpperCase();
702
+ if (method === "mobile_money") {
703
+ const mobileMoneyDescriptions = {
704
+ GH: "MTN, Vodafone Cash, AirtelTigo Money",
705
+ KE: "M-Pesa, Airtel Money",
706
+ NG: "MTN MoMo, Airtel Money",
707
+ ZA: "Mobile Money"
708
+ };
709
+ return mobileMoneyDescriptions[c] || "Mobile Money";
713
710
  }
714
- return config.description;
711
+ if (method === "card") {
712
+ return "Pay with Visa, Mastercard, or other cards";
713
+ }
714
+ if (method === "bank_transfer") {
715
+ return "Pay directly from your bank account";
716
+ }
717
+ return "";
715
718
  };
716
719
  const isGrid = layout === "grid";
717
720
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("reevit-method-selector", isGrid && "reevit-method-selector--grid"), children: [
718
721
  showLabel && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-method-selector__label", children: "Select payment method" }),
719
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(
720
- "reevit-method-selector__options",
721
- isGrid ? "reevit-method-selector__options--grid" : "reevit-method-selector__options--list"
722
- ), children: methods.map((method, index) => {
723
- const config = methodConfig[method];
724
- const isSelected = selectedMethod === method;
725
- const methodLabel = getMethodLabel(method);
726
- const methodDescription = getMethodDescription(method, provider);
727
- return /* @__PURE__ */ jsxRuntime.jsxs(
728
- "button",
729
- {
730
- type: "button",
731
- className: cn(
732
- "reevit-method-option",
733
- isGrid ? "reevit-method-option--grid" : "reevit-method-option--list",
734
- isSelected && "reevit-method-option--selected",
735
- disabled && "reevit-method-option--disabled"
736
- ),
737
- style: {
738
- animationDelay: `${index * 0.05}s`
739
- },
740
- onClick: () => onSelect(method),
741
- disabled,
742
- "aria-pressed": isSelected,
743
- children: [
744
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__icon-wrapper", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__icon", children: config.icon }) }),
745
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-method-option__content", children: [
746
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__label", children: methodLabel }),
747
- !isGrid && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__description", children: methodDescription })
748
- ] }),
749
- !isGrid && isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__check", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
750
- !isGrid && !isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__chevron", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
751
- ]
752
- },
753
- method
754
- );
755
- }) })
722
+ /* @__PURE__ */ jsxRuntime.jsx(
723
+ "div",
724
+ {
725
+ className: cn(
726
+ "reevit-method-selector__options",
727
+ isGrid ? "reevit-method-selector__options--grid" : "reevit-method-selector__options--list"
728
+ ),
729
+ style: selectedTheme?.backgroundColor ? { backgroundColor: selectedTheme.backgroundColor } : void 0,
730
+ children: methods.map((method, index) => {
731
+ const config = methodConfig[method];
732
+ const isSelected = selectedMethod === method;
733
+ const methodLabel = getMethodLabel(method);
734
+ const methodDescription = getMethodDescription(method);
735
+ const logos = getMethodLogos(country, method);
736
+ return /* @__PURE__ */ jsxRuntime.jsxs(
737
+ "button",
738
+ {
739
+ type: "button",
740
+ className: cn(
741
+ "reevit-method-option",
742
+ isGrid ? "reevit-method-option--grid" : "reevit-method-option--list",
743
+ isSelected && "reevit-method-option--selected",
744
+ disabled && "reevit-method-option--disabled"
745
+ ),
746
+ style: {
747
+ animationDelay: `${index * 0.05}s`,
748
+ borderBottomColor: selectedTheme?.borderColor
749
+ },
750
+ onClick: () => onSelect(method),
751
+ disabled,
752
+ "aria-pressed": isSelected,
753
+ children: [
754
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__icon-wrapper", children: logos.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__logos", children: logos.slice(0, 3).map((logo, i) => /* @__PURE__ */ jsxRuntime.jsx(
755
+ "img",
756
+ {
757
+ src: logo,
758
+ alt: "",
759
+ className: "reevit-method-option__logo-img"
760
+ },
761
+ i
762
+ )) }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__icon", children: config.icon }) }),
763
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-method-option__content", children: [
764
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__label", style: selectedTheme?.textColor ? { color: selectedTheme.textColor } : void 0, children: methodLabel }),
765
+ !isGrid && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__description", style: selectedTheme?.descriptionColor ? { color: selectedTheme.descriptionColor } : void 0, children: methodDescription })
766
+ ] }),
767
+ !isGrid && isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__check", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
768
+ !isGrid && !isSelected && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-method-option__chevron", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 18 15 12 9 6" }) }) })
769
+ ]
770
+ },
771
+ method
772
+ );
773
+ })
774
+ }
775
+ )
756
776
  ] });
757
777
  }
758
778
  var networks = [
@@ -920,28 +940,11 @@ function ProviderSelector({
920
940
  onSelect,
921
941
  disabled = false,
922
942
  theme,
943
+ country = "GH",
923
944
  selectedMethod,
924
945
  onMethodSelect,
925
946
  renderMethodContent
926
947
  }) {
927
- const useBorder = theme?.pspSelectorUseBorder ?? false;
928
- const bgColor = theme?.pspSelectorBgColor || "#0a0a0a";
929
- const textColor = theme?.pspSelectorTextColor || "#ffffff";
930
- const borderColor = theme?.pspSelectorBorderColor || "#374151";
931
- const getOptionStyle = (isSelected) => {
932
- if (useBorder) {
933
- return {
934
- backgroundColor: "transparent",
935
- border: `2px solid ${isSelected ? borderColor : "#374151"}`,
936
- color: isSelected ? textColor : "var(--reevit-text)"
937
- };
938
- }
939
- return {
940
- backgroundColor: isSelected ? bgColor : "transparent",
941
- border: `2px solid ${isSelected ? bgColor : "#374151"}`,
942
- color: isSelected ? textColor : "var(--reevit-text)"
943
- };
944
- };
945
948
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-psp-selector", children: [
946
949
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-selector__label", children: "Select payment provider" }),
947
950
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-selector__options", children: providers.map((provider) => {
@@ -952,7 +955,7 @@ function ProviderSelector({
952
955
  const providerMethods = sanitizeMethods(provider.provider, provider.methods);
953
956
  const isSelected = selectedProvider === provider.provider;
954
957
  const fallbackInitial = provider.name.slice(0, 1).toUpperCase();
955
- const optionStyle = getOptionStyle(isSelected);
958
+ const providerCountry = provider.countries?.[0] || country;
956
959
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-psp-accordion", children: [
957
960
  /* @__PURE__ */ jsxRuntime.jsxs(
958
961
  "button",
@@ -963,7 +966,6 @@ function ProviderSelector({
963
966
  isSelected && "reevit-psp-option--selected",
964
967
  disabled && "reevit-psp-option--disabled"
965
968
  ),
966
- style: optionStyle,
967
969
  onClick: () => onSelect(provider.provider),
968
970
  disabled,
969
971
  "aria-expanded": isSelected,
@@ -978,27 +980,46 @@ function ProviderSelector({
978
980
  }
979
981
  ) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-psp-option__logo-fallback", children: fallbackInitial }) }),
980
982
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-psp-option__content", children: [
981
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-psp-option__name", children: provider.name }),
983
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "reevit-psp-option__name", children: [
984
+ "Pay with ",
985
+ provider.name
986
+ ] }),
982
987
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-psp-option__methods", children: formatMethods(providerMethods) || meta.hint })
983
988
  ] })
984
989
  ]
985
990
  }
986
991
  ),
987
- isSelected && onMethodSelect && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-psp-accordion__content", children: [
988
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-methods", children: /* @__PURE__ */ jsxRuntime.jsx(
989
- PaymentMethodSelector,
990
- {
991
- methods: providerMethods,
992
- selectedMethod: selectedMethod || null,
993
- onSelect: onMethodSelect,
994
- disabled,
995
- provider: provider.provider,
996
- layout: "list",
997
- showLabel: false
998
- }
999
- ) }),
1000
- selectedMethod && renderMethodContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-accordion__method-content", children: renderMethodContent(provider.provider, selectedMethod) })
1001
- ] })
992
+ isSelected && onMethodSelect && /* @__PURE__ */ jsxRuntime.jsxs(
993
+ "div",
994
+ {
995
+ className: "reevit-psp-accordion__content",
996
+ style: theme?.selectedBorderColor ? {
997
+ borderTop: `1px solid ${theme.selectedBorderColor}`
998
+ } : void 0,
999
+ children: [
1000
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-methods", children: /* @__PURE__ */ jsxRuntime.jsx(
1001
+ PaymentMethodSelector,
1002
+ {
1003
+ methods: providerMethods,
1004
+ selectedMethod: selectedMethod || null,
1005
+ onSelect: onMethodSelect,
1006
+ disabled,
1007
+ provider: provider.provider,
1008
+ layout: "list",
1009
+ showLabel: false,
1010
+ country: providerCountry,
1011
+ selectedTheme: theme ? {
1012
+ backgroundColor: theme.selectedBackgroundColor,
1013
+ textColor: theme.selectedTextColor,
1014
+ descriptionColor: theme.selectedDescriptionColor,
1015
+ borderColor: theme.selectedBorderColor
1016
+ } : void 0
1017
+ }
1018
+ ) }),
1019
+ selectedMethod && renderMethodContent && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-psp-accordion__method-content", children: renderMethodContent(provider.provider, selectedMethod) })
1020
+ ]
1021
+ }
1022
+ )
1002
1023
  ] }, provider.provider);
1003
1024
  }) })
1004
1025
  ] });
@@ -2221,7 +2242,29 @@ function ReevitCheckout({
2221
2242
  ...theme || {}
2222
2243
  };
2223
2244
  }, [paymentIntent?.branding, theme]);
2224
- const themeStyles = resolvedTheme ? createThemeVariables(resolvedTheme) : {};
2245
+ const themeStyles = react.useMemo(() => {
2246
+ if (!resolvedTheme) return {};
2247
+ const vars = {};
2248
+ if (resolvedTheme.backgroundColor) {
2249
+ vars["--reevit-background"] = resolvedTheme.backgroundColor;
2250
+ vars["--reevit-surface"] = resolvedTheme.backgroundColor;
2251
+ }
2252
+ if (resolvedTheme.primaryColor) {
2253
+ vars["--reevit-text"] = resolvedTheme.primaryColor;
2254
+ }
2255
+ if (resolvedTheme.primaryForegroundColor) {
2256
+ vars["--reevit-text-secondary"] = resolvedTheme.primaryForegroundColor;
2257
+ vars["--reevit-muted"] = resolvedTheme.primaryForegroundColor;
2258
+ }
2259
+ if (resolvedTheme.borderColor) {
2260
+ vars["--reevit-border"] = resolvedTheme.borderColor;
2261
+ }
2262
+ if (resolvedTheme.borderRadius) {
2263
+ vars["--reevit-radius"] = resolvedTheme.borderRadius;
2264
+ vars["--reevit-radius-lg"] = resolvedTheme.borderRadius;
2265
+ }
2266
+ return vars;
2267
+ }, [resolvedTheme]);
2225
2268
  const brandName = resolvedTheme?.companyName;
2226
2269
  const themeMode = resolvedTheme?.darkMode;
2227
2270
  const dataTheme = react.useMemo(() => {
@@ -2419,6 +2462,7 @@ function ReevitCheckout({
2419
2462
  onSelect: handleProviderSelect,
2420
2463
  disabled: isLoading,
2421
2464
  theme: resolvedTheme,
2465
+ country: getCountryFromCurrency(currency),
2422
2466
  selectedMethod,
2423
2467
  onMethodSelect: handleMethodSelect,
2424
2468
  renderMethodContent
@@ -2435,7 +2479,14 @@ function ReevitCheckout({
2435
2479
  disabled: isLoading,
2436
2480
  provider: psp,
2437
2481
  layout: "list",
2438
- showLabel: false
2482
+ showLabel: false,
2483
+ country: getCountryFromCurrency(currency),
2484
+ selectedTheme: resolvedTheme ? {
2485
+ backgroundColor: resolvedTheme.selectedBackgroundColor,
2486
+ textColor: resolvedTheme.selectedTextColor,
2487
+ descriptionColor: resolvedTheme.selectedDescriptionColor,
2488
+ borderColor: resolvedTheme.selectedBorderColor
2489
+ } : void 0
2439
2490
  }
2440
2491
  ),
2441
2492
  selectedMethod && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reevit-method-step__actions reevit-animate-slide-up", children: selectedMethod === "mobile_money" && pspLower.includes("mpesa") && !phone ? /* @__PURE__ */ jsxRuntime.jsx(MobileMoneyForm, { onSubmit: handleMomoSubmit, onCancel: () => selectMethod(null), isLoading, initialPhone: phone }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-card-info reevit-animate-fade-in", children: [
@@ -2466,17 +2517,20 @@ function ReevitCheckout({
2466
2517
  children: [
2467
2518
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__header", children: [
2468
2519
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__branding", children: [
2469
- /* @__PURE__ */ jsxRuntime.jsx(
2520
+ resolvedTheme?.logoUrl && /* @__PURE__ */ jsxRuntime.jsx(
2470
2521
  "img",
2471
2522
  {
2472
- src: resolvedTheme?.logoUrl || "https://i.imgur.com/bzUR5Lm.png",
2473
- alt: brandName || "Reevit",
2523
+ src: resolvedTheme.logoUrl,
2524
+ alt: brandName || "",
2474
2525
  className: "reevit-modal__logo"
2475
2526
  }
2476
2527
  ),
2477
2528
  brandName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-modal__brand-name", children: brandName })
2478
2529
  ] }),
2479
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: "reevit-modal__close", onClick: handleClose, "aria-label": "Close", children: "\u2715" })
2530
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "reevit-modal__close", onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2531
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2532
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2533
+ ] }) })
2480
2534
  ] }),
2481
2535
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reevit-modal__amount", children: [
2482
2536
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reevit-modal__amount-label", children: "Amount" }),