@flopay/react 0.1.4 → 0.1.6

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.cjs CHANGED
@@ -207,7 +207,7 @@ function useBillingApiUrl() {
207
207
  var import_shared3 = require("@flopay/shared");
208
208
  var import_jsx_runtime3 = require("react/jsx-runtime");
209
209
  var WALLET_RESUME_KEY = "flopay_wallet_resume";
210
- function ProcessingOverlay({ status }) {
210
+ function ProcessingOverlay({ status, errorMessage }) {
211
211
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
212
212
  position: "fixed",
213
213
  inset: 0,
@@ -283,11 +283,21 @@ function ProcessingOverlay({ status }) {
283
283
  status === "success" && "PAYMENT SUCCESSFUL",
284
284
  status === "error" && "PAYMENT FAILED"
285
285
  ] }),
286
+ status === "error" && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: {
287
+ fontSize: 13,
288
+ color: "#6b7280",
289
+ fontWeight: 400,
290
+ maxWidth: 260,
291
+ lineHeight: 1.4,
292
+ margin: 0
293
+ }, children: errorMessage }),
286
294
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
287
295
  @keyframes flopay-spin { to { transform: rotate(360deg); } }
288
296
  @keyframes flopay-pop { 0% { transform: scale(0); } 100% { transform: scale(1); } }
289
297
  @keyframes flopay-draw { to { stroke-dashoffset: 0; } }
290
298
  @keyframes flopay-shake { 0%,100% { transform: translateX(0); } 20%,60% { transform: translateX(-4px); } 40%,80% { transform: translateX(4px); } }
299
+ @keyframes flopay-expand { 0% { opacity: 0; clip-path: inset(0 0 100% 0); transform: translateY(-8px); } 100% { opacity: 1; clip-path: inset(0 0 0 0); transform: translateY(0); } }
300
+ @keyframes flopay-fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
291
301
  ` })
292
302
  ] }) });
293
303
  }
@@ -509,10 +519,12 @@ function WalletButtonInner({
509
519
  options: {
510
520
  buttonType: { applePay: "plain", googlePay: "plain" },
511
521
  paymentMethods: {
512
- applePay: showApplePay ? "auto" : "never",
513
- googlePay: showGooglePay ? "auto" : "never",
522
+ applePay: showApplePay ? "always" : "never",
523
+ googlePay: showGooglePay ? "always" : "never",
514
524
  paypal: "never",
515
- link: "never"
525
+ link: "never",
526
+ amazonPay: "never",
527
+ klarna: "never"
516
528
  },
517
529
  layout: { overflow: "never" }
518
530
  }
@@ -543,6 +555,7 @@ function SplitCardFormInner({
543
555
  showPayPal = true,
544
556
  showApplePay = true,
545
557
  showGooglePay = true,
558
+ layout = "default",
546
559
  totalAmount = 0,
547
560
  currency = "usd",
548
561
  innerRef
@@ -552,6 +565,7 @@ function SplitCardFormInner({
552
565
  const contextBillingUrl = useBillingApiUrl();
553
566
  const [processing, setProcessing] = (0, import_react5.useState)(false);
554
567
  const [error, setError] = (0, import_react5.useState)(null);
568
+ const [showCardForm, setShowCardForm] = (0, import_react5.useState)(false);
555
569
  const [is3DSActive, setIs3DSActive] = (0, import_react5.useState)(false);
556
570
  const [fullName, setFullName] = (0, import_react5.useState)("");
557
571
  const [formReady, setFormReady] = (0, import_react5.useState)(false);
@@ -836,8 +850,265 @@ function SplitCardFormInner({
836
850
  if (!isReady) {
837
851
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { "data-testid": "flopay-loading", "aria-busy": "true", children: "Loading payment form..." });
838
852
  }
853
+ const isButtons = layout === "buttons";
854
+ const cardBorderColor = isButtons ? "#e5e7eb" : "#A4A4FF";
855
+ const cardBg = isButtons ? "white" : "#EDEDFF";
856
+ const cardFormBlock = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
857
+ backgroundColor: cardBg,
858
+ borderRadius: "8px",
859
+ padding: isButtons ? "0" : "1rem",
860
+ ...isButtons && showCardForm ? {
861
+ animation: "flopay-expand 0.4s cubic-bezier(0.16,1,0.3,1) both"
862
+ } : {}
863
+ }, children: [
864
+ isButtons && showCardForm && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
865
+ display: "flex",
866
+ alignItems: "center",
867
+ padding: "0.75rem 0 0.625rem"
868
+ }, children: [
869
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
870
+ "button",
871
+ {
872
+ type: "button",
873
+ onClick: () => setShowCardForm(false),
874
+ style: {
875
+ display: "inline-flex",
876
+ alignItems: "center",
877
+ gap: "0.5rem",
878
+ background: "none",
879
+ border: "none",
880
+ cursor: "pointer",
881
+ color: "#4b5563",
882
+ fontSize: "0.85rem",
883
+ fontWeight: 500,
884
+ padding: 0,
885
+ transition: "color 0.15s",
886
+ flexShrink: 0
887
+ },
888
+ onMouseOver: (e) => {
889
+ e.currentTarget.style.color = "#1f2937";
890
+ },
891
+ onMouseOut: (e) => {
892
+ e.currentTarget.style.color = "#4b5563";
893
+ },
894
+ "aria-label": "Back to payment methods",
895
+ children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
897
+ display: "inline-flex",
898
+ alignItems: "center",
899
+ justifyContent: "center",
900
+ width: 28,
901
+ height: 28,
902
+ borderRadius: "50%",
903
+ backgroundColor: "#f3f4f6",
904
+ transition: "background-color 0.15s"
905
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M15 18l-6-6 6-6" }) }) }),
906
+ "Go back"
907
+ ]
908
+ }
909
+ ),
910
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: 1, textAlign: "center", fontWeight: 600, fontSize: "1.05rem", color: "#262833", paddingRight: 80 }, children: "Secure card checkout" })
911
+ ] }),
912
+ !isButtons && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: "Secure card checkout" }),
913
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
914
+ backgroundColor: "white",
915
+ border: `1px solid ${cardBorderColor}`,
916
+ borderTopLeftRadius: "8px",
917
+ borderTopRightRadius: "8px",
918
+ padding: "10px"
919
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardNumberElement, { onReady: () => setFormReady(true) }) }),
920
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex" }, children: [
921
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
922
+ flex: 1,
923
+ backgroundColor: "white",
924
+ border: `1px solid ${cardBorderColor}`,
925
+ borderTop: "none",
926
+ borderRight: "none",
927
+ borderBottomLeftRadius: "8px",
928
+ padding: "10px"
929
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardExpiryElement, {}) }),
930
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
931
+ flex: 1,
932
+ backgroundColor: "white",
933
+ border: `1px solid ${cardBorderColor}`,
934
+ borderTop: "none",
935
+ borderBottomRightRadius: "8px",
936
+ padding: "10px"
937
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardCvcElement, {}) })
938
+ ] }),
939
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
940
+ backgroundColor: "white",
941
+ border: `1px solid ${cardBorderColor}`,
942
+ borderRadius: "8px",
943
+ marginTop: "0.5rem",
944
+ padding: "10px"
945
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
946
+ "input",
947
+ {
948
+ placeholder: "Full Name on Card",
949
+ autoComplete: "cc-name",
950
+ value: fullName,
951
+ onChange: (e) => handleNameChange(e.target.value),
952
+ disabled: isSubmitting,
953
+ required: true,
954
+ style: {
955
+ width: "100%",
956
+ border: "none",
957
+ outline: "none",
958
+ fontSize: "16px",
959
+ fontFamily: "Poppins, sans-serif",
960
+ color: "#262833"
961
+ }
962
+ }
963
+ ) }),
964
+ displayError && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
965
+ margin: "0.75rem 0",
966
+ padding: "0.625rem 0.875rem",
967
+ background: "#FEF2F2",
968
+ border: "1px solid #FECACA",
969
+ borderRadius: "8px",
970
+ color: "#991B1B",
971
+ fontSize: "0.85rem",
972
+ fontWeight: 600,
973
+ display: "flex",
974
+ alignItems: "center",
975
+ gap: "0.5rem"
976
+ }, children: [
977
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
978
+ displayError
979
+ ] }),
980
+ children ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
981
+ "button",
982
+ {
983
+ type: "submit",
984
+ disabled: !formReady || isSubmitting,
985
+ "data-testid": "flopay-submit",
986
+ style: {
987
+ width: "100%",
988
+ padding: "0.875rem",
989
+ marginTop: "1rem",
990
+ backgroundColor: "#4A49FF",
991
+ color: "white",
992
+ border: "none",
993
+ borderRadius: "8px",
994
+ fontSize: "1rem",
995
+ fontWeight: 600,
996
+ cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
997
+ opacity: !formReady || isSubmitting ? 0.5 : 1
998
+ },
999
+ children: isSubmitting ? "PROCESSING..." : submitLabel
1000
+ }
1001
+ ),
1002
+ !isButtons && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
1003
+ backgroundColor: "#EFF9F0",
1004
+ borderRadius: "8px",
1005
+ padding: "0.75rem",
1006
+ marginTop: "0.75rem",
1007
+ textAlign: "center",
1008
+ fontSize: "0.85rem",
1009
+ fontWeight: 600,
1010
+ color: "#7DAD3A"
1011
+ }, children: "Secure Card Checkout" })
1012
+ ] });
1013
+ if (layout === "buttons") {
1014
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
1015
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
1016
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
1017
+ display: showCardForm ? "none" : "flex",
1018
+ flexDirection: "column",
1019
+ gap: "0.5rem"
1020
+ }, children: [
1021
+ showPayPal && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: paypalOptions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1022
+ PayPalButtonInner,
1023
+ {
1024
+ sessionId,
1025
+ email,
1026
+ billingApiUrl: resolvedBillingApiUrl,
1027
+ onTokenizedBody: dispatchTokenizedBody,
1028
+ onErrorChange: updateError,
1029
+ isProcessing: isSubmitting
1030
+ }
1031
+ ) }),
1032
+ showWallets && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1033
+ WalletButtonInner,
1034
+ {
1035
+ sessionId,
1036
+ email,
1037
+ billingApiUrl: resolvedBillingApiUrl,
1038
+ showApplePay,
1039
+ showGooglePay,
1040
+ onTokenizedBody: dispatchTokenizedBody,
1041
+ onErrorChange: updateError
1042
+ }
1043
+ ) }),
1044
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1045
+ "button",
1046
+ {
1047
+ type: "button",
1048
+ onClick: () => setShowCardForm(true),
1049
+ style: {
1050
+ width: "100%",
1051
+ padding: "0.9rem 1rem",
1052
+ backgroundColor: "white",
1053
+ color: "#262833",
1054
+ border: "1px solid #d1d5db",
1055
+ borderRadius: "8px",
1056
+ fontSize: "0.95rem",
1057
+ fontWeight: 600,
1058
+ cursor: "pointer",
1059
+ display: "flex",
1060
+ alignItems: "center",
1061
+ justifyContent: "center",
1062
+ gap: "0.625rem",
1063
+ transition: "border-color 0.2s, box-shadow 0.2s, transform 0.1s",
1064
+ boxShadow: "0 1px 2px rgba(0,0,0,0.04)"
1065
+ },
1066
+ onMouseOver: (e) => {
1067
+ e.currentTarget.style.borderColor = "#A4A4FF";
1068
+ e.currentTarget.style.boxShadow = "0 0 0 1px #A4A4FF, 0 2px 8px rgba(74,73,255,0.08)";
1069
+ },
1070
+ onMouseOut: (e) => {
1071
+ e.currentTarget.style.borderColor = "#d1d5db";
1072
+ e.currentTarget.style.boxShadow = "0 1px 2px rgba(0,0,0,0.04)";
1073
+ },
1074
+ onMouseDown: (e) => {
1075
+ e.currentTarget.style.transform = "scale(0.985)";
1076
+ },
1077
+ onMouseUp: (e) => {
1078
+ e.currentTarget.style.transform = "scale(1)";
1079
+ },
1080
+ children: [
1081
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1082
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { width: "20", height: "14", x: "2", y: "5", rx: "2" }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "2", x2: "22", y1: "10", y2: "10" })
1084
+ ] }),
1085
+ "Credit / Debit Card",
1086
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "#9ca3af", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { marginLeft: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M9 18l6-6-6-6" }) })
1087
+ ]
1088
+ }
1089
+ ),
1090
+ displayError && !showCardForm && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { role: "alert", "data-testid": "flopay-error", style: {
1091
+ margin: "0.25rem 0",
1092
+ padding: "0.625rem 0.875rem",
1093
+ background: "#FEF2F2",
1094
+ border: "1px solid #FECACA",
1095
+ borderRadius: "8px",
1096
+ color: "#991B1B",
1097
+ fontSize: "0.85rem",
1098
+ fontWeight: 600,
1099
+ display: "flex",
1100
+ alignItems: "center",
1101
+ gap: "0.5rem"
1102
+ }, children: [
1103
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", style: { flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z", stroke: "#DC2626", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }),
1104
+ displayError
1105
+ ] })
1106
+ ] }),
1107
+ showCardForm && cardFormBlock
1108
+ ] });
1109
+ }
839
1110
  return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit: handleSubmit, className, style: { position: "relative" }, children: [
840
- overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ProcessingOverlay, { status: overlayStatus }),
1111
+ overlayStatus && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ProcessingOverlay, { status: overlayStatus, errorMessage: displayError }),
841
1112
  showWallets && stripeInstance && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_stripe_js.Elements, { stripe: stripeInstance, options: walletOptions, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
842
1113
  WalletButtonInner,
843
1114
  {
@@ -873,93 +1144,7 @@ function SplitCardFormInner({
873
1144
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "or pay with card" }),
874
1145
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { flex: 1, height: 1, backgroundColor: "#ddd" } })
875
1146
  ] }),
876
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { backgroundColor: "#EDEDFF", borderRadius: "8px", padding: "1rem" }, children: [
877
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { textAlign: "center", fontWeight: 600, fontSize: "1.1rem", padding: "0.5rem 0", color: "#262833" }, children: "Secure card checkout" }),
878
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
879
- backgroundColor: "white",
880
- border: "1px solid #A4A4FF",
881
- borderTopLeftRadius: "8px",
882
- borderTopRightRadius: "8px",
883
- padding: "10px"
884
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardNumberElement, { onReady: () => setFormReady(true) }) }),
885
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex" }, children: [
886
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
887
- flex: 1,
888
- backgroundColor: "white",
889
- border: "1px solid #A4A4FF",
890
- borderTop: "none",
891
- borderRight: "none",
892
- borderBottomLeftRadius: "8px",
893
- padding: "10px"
894
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardExpiryElement, {}) }),
895
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
896
- flex: 1,
897
- backgroundColor: "white",
898
- border: "1px solid #A4A4FF",
899
- borderTop: "none",
900
- borderBottomRightRadius: "8px",
901
- padding: "10px"
902
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CardCvcElement, {}) })
903
- ] }),
904
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
905
- backgroundColor: "white",
906
- border: "1px solid #A4A4FF",
907
- borderRadius: "8px",
908
- marginTop: "0.5rem",
909
- padding: "10px"
910
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
911
- "input",
912
- {
913
- placeholder: "Full Name on Card",
914
- autoComplete: "cc-name",
915
- value: fullName,
916
- onChange: (e) => handleNameChange(e.target.value),
917
- disabled: isSubmitting,
918
- required: true,
919
- style: {
920
- width: "100%",
921
- border: "none",
922
- outline: "none",
923
- fontSize: "16px",
924
- fontFamily: "Poppins, sans-serif",
925
- color: "#262833"
926
- }
927
- }
928
- ) }),
929
- displayError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { role: "alert", "data-testid": "flopay-error", style: { color: "red", margin: "0.75rem 0", fontSize: "0.9rem" }, children: displayError }),
930
- children ?? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
931
- "button",
932
- {
933
- type: "submit",
934
- disabled: !formReady || isSubmitting,
935
- "data-testid": "flopay-submit",
936
- style: {
937
- width: "100%",
938
- padding: "0.875rem",
939
- marginTop: "1rem",
940
- backgroundColor: "#4A49FF",
941
- color: "white",
942
- border: "none",
943
- borderRadius: "8px",
944
- fontSize: "1rem",
945
- fontWeight: 600,
946
- cursor: !formReady || isSubmitting ? "not-allowed" : "pointer",
947
- opacity: !formReady || isSubmitting ? 0.5 : 1
948
- },
949
- children: isSubmitting ? "PROCESSING..." : submitLabel
950
- }
951
- ),
952
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
953
- backgroundColor: "#EFF9F0",
954
- borderRadius: "8px",
955
- padding: "0.75rem",
956
- marginTop: "0.75rem",
957
- textAlign: "center",
958
- fontSize: "0.85rem",
959
- fontWeight: 600,
960
- color: "#7DAD3A"
961
- }, children: "Secure Card Checkout" })
962
- ] })
1147
+ cardFormBlock
963
1148
  ] });
964
1149
  }
965
1150
 
@@ -978,6 +1163,7 @@ function FloPayCheckout({
978
1163
  showPayPal = true,
979
1164
  showApplePay = true,
980
1165
  showGooglePay = true,
1166
+ layout,
981
1167
  submitLabel,
982
1168
  className,
983
1169
  children,
@@ -1353,6 +1539,7 @@ function FloPayCheckout({
1353
1539
  showPayPal,
1354
1540
  showApplePay,
1355
1541
  showGooglePay,
1542
+ layout,
1356
1543
  submitLabel,
1357
1544
  className
1358
1545
  }