pesafy 0.1.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.
- package/README.md +177 -0
- package/dist/components/react/index.cjs +230 -0
- package/dist/components/react/index.cjs.map +1 -0
- package/dist/components/react/index.d.cts +63 -0
- package/dist/components/react/index.d.ts +63 -0
- package/dist/components/react/index.js +200 -0
- package/dist/components/react/index.js.map +1 -0
- package/dist/components/react/styles.css +90 -0
- package/dist/components/react/styles.css.map +1 -0
- package/dist/components/react/styles.d.cts +2 -0
- package/dist/components/react/styles.d.ts +2 -0
- package/dist/index.cjs +729 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +416 -0
- package/dist/index.d.ts +416 -0
- package/dist/index.js +717 -0
- package/dist/index.js.map +1 -0
- package/package.json +105 -0
- package/src/components/vue/PaymentButton.vue +71 -0
- package/src/components/vue/PaymentForm.vue +164 -0
- package/src/components/vue/PaymentStatus.vue +68 -0
- package/src/components/vue/QRCode.vue +39 -0
- package/src/components/vue/index.ts +13 -0
- package/src/components/vue/shims-vue.d.ts +39 -0
- package/src/components/vue/types.ts +15 -0
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// src/components/react/PaymentButton.tsx
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
function PaymentButton({
|
|
4
|
+
amount,
|
|
5
|
+
onPay,
|
|
6
|
+
disabled = false,
|
|
7
|
+
loading = false,
|
|
8
|
+
children,
|
|
9
|
+
className = ""
|
|
10
|
+
}) {
|
|
11
|
+
const handleClick = async () => {
|
|
12
|
+
if (disabled || loading) return;
|
|
13
|
+
await onPay({ amount });
|
|
14
|
+
};
|
|
15
|
+
return /* @__PURE__ */ jsx(
|
|
16
|
+
"button",
|
|
17
|
+
{
|
|
18
|
+
type: "button",
|
|
19
|
+
onClick: handleClick,
|
|
20
|
+
disabled: disabled || loading,
|
|
21
|
+
className: `pesafy-payment-btn ${className}`,
|
|
22
|
+
"aria-busy": loading,
|
|
23
|
+
children: loading ? /* @__PURE__ */ jsx("span", { className: "pesafy-payment-btn-loading", children: "Processing..." }) : children ?? `Pay KES ${amount.toLocaleString()}`
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// src/components/react/PaymentForm.tsx
|
|
29
|
+
import { useState } from "react";
|
|
30
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
31
|
+
function PaymentForm({
|
|
32
|
+
onSubmit,
|
|
33
|
+
defaultAmount = 0,
|
|
34
|
+
defaultReference = "",
|
|
35
|
+
disabled = false,
|
|
36
|
+
loading = false,
|
|
37
|
+
className = ""
|
|
38
|
+
}) {
|
|
39
|
+
const [amount, setAmount] = useState(defaultAmount.toString());
|
|
40
|
+
const [phone, setPhone] = useState("");
|
|
41
|
+
const [reference, setReference] = useState(defaultReference);
|
|
42
|
+
const [desc, setDesc] = useState("Payment");
|
|
43
|
+
const handleSubmit = async (e) => {
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
if (disabled || loading) return;
|
|
46
|
+
const amt = Number.parseFloat(amount);
|
|
47
|
+
if (Number.isNaN(amt) || amt <= 0) return;
|
|
48
|
+
const cleaned = phone.replace(/\D/g, "");
|
|
49
|
+
if (cleaned.length < 9) return;
|
|
50
|
+
await onSubmit({
|
|
51
|
+
amount: amt,
|
|
52
|
+
phoneNumber: phone,
|
|
53
|
+
accountReference: reference || `REF-${Date.now()}`,
|
|
54
|
+
transactionDesc: desc
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
return /* @__PURE__ */ jsxs(
|
|
58
|
+
"form",
|
|
59
|
+
{
|
|
60
|
+
onSubmit: handleSubmit,
|
|
61
|
+
className: `pesafy-payment-form ${className}`,
|
|
62
|
+
children: [
|
|
63
|
+
/* @__PURE__ */ jsxs("div", { className: "pesafy-payment-form-field", children: [
|
|
64
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: "pesafy-amount", children: "Amount (KES)" }),
|
|
65
|
+
/* @__PURE__ */ jsx2(
|
|
66
|
+
"input",
|
|
67
|
+
{
|
|
68
|
+
id: "pesafy-amount",
|
|
69
|
+
type: "number",
|
|
70
|
+
min: "1",
|
|
71
|
+
step: "0.01",
|
|
72
|
+
value: amount,
|
|
73
|
+
onChange: (e) => setAmount(e.target.value),
|
|
74
|
+
placeholder: "100",
|
|
75
|
+
disabled,
|
|
76
|
+
required: true
|
|
77
|
+
}
|
|
78
|
+
)
|
|
79
|
+
] }),
|
|
80
|
+
/* @__PURE__ */ jsxs("div", { className: "pesafy-payment-form-field", children: [
|
|
81
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: "pesafy-phone", children: "M-Pesa Phone Number" }),
|
|
82
|
+
/* @__PURE__ */ jsx2(
|
|
83
|
+
"input",
|
|
84
|
+
{
|
|
85
|
+
id: "pesafy-phone",
|
|
86
|
+
type: "tel",
|
|
87
|
+
value: phone,
|
|
88
|
+
onChange: (e) => setPhone(e.target.value),
|
|
89
|
+
placeholder: "07XX XXX XXX or 2547XX XXX XXX",
|
|
90
|
+
disabled,
|
|
91
|
+
required: true
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
] }),
|
|
95
|
+
/* @__PURE__ */ jsxs("div", { className: "pesafy-payment-form-field", children: [
|
|
96
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: "pesafy-reference", children: "Reference" }),
|
|
97
|
+
/* @__PURE__ */ jsx2(
|
|
98
|
+
"input",
|
|
99
|
+
{
|
|
100
|
+
id: "pesafy-reference",
|
|
101
|
+
type: "text",
|
|
102
|
+
value: reference,
|
|
103
|
+
onChange: (e) => setReference(e.target.value),
|
|
104
|
+
placeholder: "ORDER-123",
|
|
105
|
+
disabled,
|
|
106
|
+
maxLength: 12
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
] }),
|
|
110
|
+
/* @__PURE__ */ jsxs("div", { className: "pesafy-payment-form-field", children: [
|
|
111
|
+
/* @__PURE__ */ jsx2("label", { htmlFor: "pesafy-desc", children: "Description" }),
|
|
112
|
+
/* @__PURE__ */ jsx2(
|
|
113
|
+
"input",
|
|
114
|
+
{
|
|
115
|
+
id: "pesafy-desc",
|
|
116
|
+
type: "text",
|
|
117
|
+
value: desc,
|
|
118
|
+
onChange: (e) => setDesc(e.target.value),
|
|
119
|
+
placeholder: "Payment",
|
|
120
|
+
disabled,
|
|
121
|
+
maxLength: 13
|
|
122
|
+
}
|
|
123
|
+
)
|
|
124
|
+
] }),
|
|
125
|
+
/* @__PURE__ */ jsx2(
|
|
126
|
+
"button",
|
|
127
|
+
{
|
|
128
|
+
type: "submit",
|
|
129
|
+
disabled: disabled || loading,
|
|
130
|
+
className: "pesafy-payment-form-submit",
|
|
131
|
+
"aria-busy": loading,
|
|
132
|
+
children: loading ? "Processing..." : "Pay with M-Pesa"
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/components/react/PaymentStatus.tsx
|
|
141
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
142
|
+
function PaymentStatus({
|
|
143
|
+
status,
|
|
144
|
+
message,
|
|
145
|
+
transactionId,
|
|
146
|
+
children,
|
|
147
|
+
className = ""
|
|
148
|
+
}) {
|
|
149
|
+
if (status === "idle" && !children) return null;
|
|
150
|
+
return /* @__PURE__ */ jsxs2(
|
|
151
|
+
"div",
|
|
152
|
+
{
|
|
153
|
+
className: `pesafy-payment-status pesafy-payment-status--${status} ${className}`,
|
|
154
|
+
role: "status",
|
|
155
|
+
"aria-live": "polite",
|
|
156
|
+
children: [
|
|
157
|
+
status === "pending" && (children ?? /* @__PURE__ */ jsx3("span", { children: "Waiting for payment..." })),
|
|
158
|
+
status === "success" && (children ?? /* @__PURE__ */ jsxs2("span", { children: [
|
|
159
|
+
"Payment successful",
|
|
160
|
+
transactionId && ` (${transactionId})`,
|
|
161
|
+
message && ` - ${message}`
|
|
162
|
+
] })),
|
|
163
|
+
status === "error" && (children ?? /* @__PURE__ */ jsxs2("span", { children: [
|
|
164
|
+
"Payment failed",
|
|
165
|
+
message && ` - ${message}`
|
|
166
|
+
] })),
|
|
167
|
+
status === "idle" && children
|
|
168
|
+
]
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/components/react/QRCode.tsx
|
|
174
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
175
|
+
function QRCode({
|
|
176
|
+
base64,
|
|
177
|
+
alt = "M-Pesa QR Code",
|
|
178
|
+
size = 300,
|
|
179
|
+
className = ""
|
|
180
|
+
}) {
|
|
181
|
+
const src = base64.startsWith("data:") ? base64 : `data:image/png;base64,${base64}`;
|
|
182
|
+
return /* @__PURE__ */ jsx4(
|
|
183
|
+
"img",
|
|
184
|
+
{
|
|
185
|
+
src,
|
|
186
|
+
alt,
|
|
187
|
+
width: size,
|
|
188
|
+
height: size,
|
|
189
|
+
className: `pesafy-qrcode ${className}`,
|
|
190
|
+
loading: "lazy"
|
|
191
|
+
}
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
export {
|
|
195
|
+
PaymentButton,
|
|
196
|
+
PaymentForm,
|
|
197
|
+
PaymentStatus,
|
|
198
|
+
QRCode
|
|
199
|
+
};
|
|
200
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/react/PaymentButton.tsx","../../../src/components/react/PaymentForm.tsx","../../../src/components/react/PaymentStatus.tsx","../../../src/components/react/QRCode.tsx"],"sourcesContent":["/**\n * PaymentButton - Trigger M-Pesa STK Push payment\n * Call onPay with payment details; parent handles API call (credentials stay server-side)\n */\n\nimport type { ReactNode } from \"react\";\n\nexport interface PaymentButtonProps {\n amount: number;\n /** Called when user clicks pay. Parent should call your backend which uses Pesafy */\n onPay: (params: { amount: number }) => void | Promise<void>;\n disabled?: boolean;\n loading?: boolean;\n children?: ReactNode;\n className?: string;\n}\n\nexport function PaymentButton({\n amount,\n onPay,\n disabled = false,\n loading = false,\n children,\n className = \"\",\n}: PaymentButtonProps) {\n const handleClick = async () => {\n if (disabled || loading) return;\n await onPay({ amount });\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={disabled || loading}\n className={`pesafy-payment-btn ${className}`}\n aria-busy={loading}\n >\n {loading ? (\n <span className=\"pesafy-payment-btn-loading\">Processing...</span>\n ) : (\n (children ?? `Pay KES ${amount.toLocaleString()}`)\n )}\n </button>\n );\n}\n","/**\n * PaymentForm - Collect payment details for M-Pesa STK Push\n * Parent receives form data and handles API call (credentials stay server-side)\n */\n\nimport { type FormEvent, useState } from \"react\";\n\nexport interface PaymentFormData {\n amount: number;\n phoneNumber: string;\n accountReference: string;\n transactionDesc: string;\n}\n\nexport interface PaymentFormProps {\n /** Called on submit. Parent should call your backend which uses Pesafy stkPush */\n onSubmit: (data: PaymentFormData) => void | Promise<void>;\n defaultAmount?: number;\n defaultReference?: string;\n disabled?: boolean;\n loading?: boolean;\n className?: string;\n}\n\nexport function PaymentForm({\n onSubmit,\n defaultAmount = 0,\n defaultReference = \"\",\n disabled = false,\n loading = false,\n className = \"\",\n}: PaymentFormProps) {\n const [amount, setAmount] = useState(defaultAmount.toString());\n const [phone, setPhone] = useState(\"\");\n const [reference, setReference] = useState(defaultReference);\n const [desc, setDesc] = useState(\"Payment\");\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n if (disabled || loading) return;\n\n const amt = Number.parseFloat(amount);\n if (Number.isNaN(amt) || amt <= 0) return;\n\n const cleaned = phone.replace(/\\D/g, \"\");\n if (cleaned.length < 9) return;\n\n await onSubmit({\n amount: amt,\n phoneNumber: phone,\n accountReference: reference || `REF-${Date.now()}`,\n transactionDesc: desc,\n });\n };\n\n return (\n <form\n onSubmit={handleSubmit}\n className={`pesafy-payment-form ${className}`}\n >\n <div className=\"pesafy-payment-form-field\">\n <label htmlFor=\"pesafy-amount\">Amount (KES)</label>\n <input\n id=\"pesafy-amount\"\n type=\"number\"\n min=\"1\"\n step=\"0.01\"\n value={amount}\n onChange={(e) => setAmount((e.target as HTMLInputElement).value)}\n placeholder=\"100\"\n disabled={disabled}\n required\n />\n </div>\n <div className=\"pesafy-payment-form-field\">\n <label htmlFor=\"pesafy-phone\">M-Pesa Phone Number</label>\n <input\n id=\"pesafy-phone\"\n type=\"tel\"\n value={phone}\n onChange={(e) => setPhone((e.target as HTMLInputElement).value)}\n placeholder=\"07XX XXX XXX or 2547XX XXX XXX\"\n disabled={disabled}\n required\n />\n </div>\n <div className=\"pesafy-payment-form-field\">\n <label htmlFor=\"pesafy-reference\">Reference</label>\n <input\n id=\"pesafy-reference\"\n type=\"text\"\n value={reference}\n onChange={(e) => setReference((e.target as HTMLInputElement).value)}\n placeholder=\"ORDER-123\"\n disabled={disabled}\n maxLength={12}\n />\n </div>\n <div className=\"pesafy-payment-form-field\">\n <label htmlFor=\"pesafy-desc\">Description</label>\n <input\n id=\"pesafy-desc\"\n type=\"text\"\n value={desc}\n onChange={(e) => setDesc((e.target as HTMLInputElement).value)}\n placeholder=\"Payment\"\n disabled={disabled}\n maxLength={13}\n />\n </div>\n <button\n type=\"submit\"\n disabled={disabled || loading}\n className=\"pesafy-payment-form-submit\"\n aria-busy={loading}\n >\n {loading ? \"Processing...\" : \"Pay with M-Pesa\"}\n </button>\n </form>\n );\n}\n","/**\n * PaymentStatus - Display payment state (pending, success, failed)\n */\n\nimport type { ReactNode } from \"react\";\n\nexport type PaymentStatusState = \"idle\" | \"pending\" | \"success\" | \"error\";\n\nexport interface PaymentStatusProps {\n status: PaymentStatusState;\n /** Optional message for success/error states */\n message?: string;\n /** Optional transaction/callback data */\n transactionId?: string;\n children?: ReactNode;\n className?: string;\n}\n\nexport function PaymentStatus({\n status,\n message,\n transactionId,\n children,\n className = \"\",\n}: PaymentStatusProps) {\n if (status === \"idle\" && !children) return null;\n\n return (\n <div\n className={`pesafy-payment-status pesafy-payment-status--${status} ${className}`}\n role=\"status\"\n aria-live=\"polite\"\n >\n {status === \"pending\" &&\n (children ?? <span>Waiting for payment...</span>)}\n {status === \"success\" &&\n (children ?? (\n <span>\n Payment successful\n {transactionId && ` (${transactionId})`}\n {message && ` - ${message}`}\n </span>\n ))}\n {status === \"error\" &&\n (children ?? (\n <span>\n Payment failed\n {message && ` - ${message}`}\n </span>\n ))}\n {status === \"idle\" && children}\n </div>\n );\n}\n","/**\n * QRCode - Display M-Pesa Dynamic QR code\n * Pass base64 image from mpesa.qrCode() response\n */\n\nexport interface QRCodeProps {\n /** Base64 QR code image from Dynamic QR API */\n base64: string;\n alt?: string;\n size?: number;\n className?: string;\n}\n\nexport function QRCode({\n base64,\n alt = \"M-Pesa QR Code\",\n size = 300,\n className = \"\",\n}: QRCodeProps) {\n const src = base64.startsWith(\"data:\")\n ? base64\n : `data:image/png;base64,${base64}`;\n\n return (\n <img\n src={src}\n alt={alt}\n width={size}\n height={size}\n className={`pesafy-qrcode ${className}`}\n loading=\"lazy\"\n />\n );\n}\n"],"mappings":";AAuCQ;AAtBD,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,UAAU;AAAA,EACV;AAAA,EACA,YAAY;AACd,GAAuB;AACrB,QAAM,cAAc,YAAY;AAC9B,QAAI,YAAY,QAAS;AACzB,UAAM,MAAM,EAAE,OAAO,CAAC;AAAA,EACxB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,UAAU,YAAY;AAAA,MACtB,WAAW,sBAAsB,SAAS;AAAA,MAC1C,aAAW;AAAA,MAEV,oBACC,oBAAC,UAAK,WAAU,8BAA6B,2BAAa,IAEzD,YAAY,WAAW,OAAO,eAAe,CAAC;AAAA;AAAA,EAEnD;AAEJ;;;ACxCA,SAAyB,gBAAgB;AAuDnC,SACE,OAAAA,MADF;AApCC,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,YAAY;AACd,GAAqB;AACnB,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,cAAc,SAAS,CAAC;AAC7D,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,gBAAgB;AAC3D,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,SAAS;AAE1C,QAAM,eAAe,OAAO,MAAiB;AAC3C,MAAE,eAAe;AACjB,QAAI,YAAY,QAAS;AAEzB,UAAM,MAAM,OAAO,WAAW,MAAM;AACpC,QAAI,OAAO,MAAM,GAAG,KAAK,OAAO,EAAG;AAEnC,UAAM,UAAU,MAAM,QAAQ,OAAO,EAAE;AACvC,QAAI,QAAQ,SAAS,EAAG;AAExB,UAAM,SAAS;AAAA,MACb,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,kBAAkB,aAAa,OAAO,KAAK,IAAI,CAAC;AAAA,MAChD,iBAAiB;AAAA,IACnB,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,UAAU;AAAA,MACV,WAAW,uBAAuB,SAAS;AAAA,MAE3C;AAAA,6BAAC,SAAI,WAAU,6BACb;AAAA,0BAAAA,KAAC,WAAM,SAAQ,iBAAgB,0BAAY;AAAA,UAC3C,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,KAAI;AAAA,cACJ,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,UAAW,EAAE,OAA4B,KAAK;AAAA,cAC/D,aAAY;AAAA,cACZ;AAAA,cACA,UAAQ;AAAA;AAAA,UACV;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAAA,KAAC,WAAM,SAAQ,gBAAe,iCAAmB;AAAA,UACjD,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,SAAU,EAAE,OAA4B,KAAK;AAAA,cAC9D,aAAY;AAAA,cACZ;AAAA,cACA,UAAQ;AAAA;AAAA,UACV;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAAA,KAAC,WAAM,SAAQ,oBAAmB,uBAAS;AAAA,UAC3C,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,aAAc,EAAE,OAA4B,KAAK;AAAA,cAClE,aAAY;AAAA,cACZ;AAAA,cACA,WAAW;AAAA;AAAA,UACb;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAAA,KAAC,WAAM,SAAQ,eAAc,yBAAW;AAAA,UACxC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,QAAS,EAAE,OAA4B,KAAK;AAAA,cAC7D,aAAY;AAAA,cACZ;AAAA,cACA,WAAW;AAAA;AAAA,UACb;AAAA,WACF;AAAA,QACA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,UAAU,YAAY;AAAA,YACtB,WAAU;AAAA,YACV,aAAW;AAAA,YAEV,oBAAU,kBAAkB;AAAA;AAAA,QAC/B;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACtFqB,gBAAAC,MAGX,QAAAC,aAHW;AAhBd,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAuB;AACrB,MAAI,WAAW,UAAU,CAAC,SAAU,QAAO;AAE3C,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,gDAAgD,MAAM,IAAI,SAAS;AAAA,MAC9E,MAAK;AAAA,MACL,aAAU;AAAA,MAET;AAAA,mBAAW,cACT,YAAY,gBAAAD,KAAC,UAAK,oCAAsB;AAAA,QAC1C,WAAW,cACT,YACC,gBAAAC,MAAC,UAAK;AAAA;AAAA,UAEH,iBAAiB,KAAK,aAAa;AAAA,UACnC,WAAW,MAAM,OAAO;AAAA,WAC3B;AAAA,QAEH,WAAW,YACT,YACC,gBAAAA,MAAC,UAAK;AAAA;AAAA,UAEH,WAAW,MAAM,OAAO;AAAA,WAC3B;AAAA,QAEH,WAAW,UAAU;AAAA;AAAA;AAAA,EACxB;AAEJ;;;AC7BI,gBAAAC,YAAA;AAXG,SAAS,OAAO;AAAA,EACrB;AAAA,EACA,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AACd,GAAgB;AACd,QAAM,MAAM,OAAO,WAAW,OAAO,IACjC,SACA,yBAAyB,MAAM;AAEnC,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW,iBAAiB,SAAS;AAAA,MACrC,SAAQ;AAAA;AAAA,EACV;AAEJ;","names":["jsx","jsx","jsxs","jsx"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* src/components/react/styles.css */
|
|
2
|
+
.pesafy-payment-btn {
|
|
3
|
+
display: inline-flex;
|
|
4
|
+
align-items: center;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
padding: 0.75rem 1.5rem;
|
|
7
|
+
font-size: 1rem;
|
|
8
|
+
font-weight: 600;
|
|
9
|
+
border: none;
|
|
10
|
+
border-radius: 0.5rem;
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
background: #00a651;
|
|
13
|
+
color: white;
|
|
14
|
+
transition: background 0.2s, opacity 0.2s;
|
|
15
|
+
}
|
|
16
|
+
.pesafy-payment-btn:hover:not(:disabled) {
|
|
17
|
+
background: #008f45;
|
|
18
|
+
}
|
|
19
|
+
.pesafy-payment-btn:disabled {
|
|
20
|
+
opacity: 0.6;
|
|
21
|
+
cursor: not-allowed;
|
|
22
|
+
}
|
|
23
|
+
.pesafy-payment-btn-loading {
|
|
24
|
+
opacity: 0.9;
|
|
25
|
+
}
|
|
26
|
+
.pesafy-payment-form {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-direction: column;
|
|
29
|
+
gap: 1rem;
|
|
30
|
+
max-width: 24rem;
|
|
31
|
+
}
|
|
32
|
+
.pesafy-payment-form-field {
|
|
33
|
+
display: flex;
|
|
34
|
+
flex-direction: column;
|
|
35
|
+
gap: 0.25rem;
|
|
36
|
+
}
|
|
37
|
+
.pesafy-payment-form-field label {
|
|
38
|
+
font-size: 0.875rem;
|
|
39
|
+
font-weight: 500;
|
|
40
|
+
}
|
|
41
|
+
.pesafy-payment-form-field input {
|
|
42
|
+
padding: 0.5rem 0.75rem;
|
|
43
|
+
font-size: 1rem;
|
|
44
|
+
border: 1px solid #d1d5db;
|
|
45
|
+
border-radius: 0.375rem;
|
|
46
|
+
}
|
|
47
|
+
.pesafy-payment-form-field input:focus {
|
|
48
|
+
outline: none;
|
|
49
|
+
border-color: #00a651;
|
|
50
|
+
box-shadow: 0 0 0 2px rgba(0, 166, 81, 0.2);
|
|
51
|
+
}
|
|
52
|
+
.pesafy-payment-form-submit {
|
|
53
|
+
padding: 0.75rem 1.5rem;
|
|
54
|
+
font-size: 1rem;
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
border: none;
|
|
57
|
+
border-radius: 0.5rem;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
background: #00a651;
|
|
60
|
+
color: white;
|
|
61
|
+
margin-top: 0.5rem;
|
|
62
|
+
}
|
|
63
|
+
.pesafy-payment-form-submit:hover:not(:disabled) {
|
|
64
|
+
background: #008f45;
|
|
65
|
+
}
|
|
66
|
+
.pesafy-payment-form-submit:disabled {
|
|
67
|
+
opacity: 0.6;
|
|
68
|
+
cursor: not-allowed;
|
|
69
|
+
}
|
|
70
|
+
.pesafy-qrcode {
|
|
71
|
+
display: block;
|
|
72
|
+
}
|
|
73
|
+
.pesafy-payment-status {
|
|
74
|
+
padding: 0.75rem 1rem;
|
|
75
|
+
border-radius: 0.375rem;
|
|
76
|
+
font-size: 0.875rem;
|
|
77
|
+
}
|
|
78
|
+
.pesafy-payment-status--pending {
|
|
79
|
+
background: #fef3c7;
|
|
80
|
+
color: #92400e;
|
|
81
|
+
}
|
|
82
|
+
.pesafy-payment-status--success {
|
|
83
|
+
background: #d1fae5;
|
|
84
|
+
color: #065f46;
|
|
85
|
+
}
|
|
86
|
+
.pesafy-payment-status--error {
|
|
87
|
+
background: #fee2e2;
|
|
88
|
+
color: #991b1b;
|
|
89
|
+
}
|
|
90
|
+
/*# sourceMappingURL=styles.css.map */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/react/styles.css"],"sourcesContent":["/* Pesafy React Components - Base styles */\n\n.pesafy-payment-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem 1.5rem;\n font-size: 1rem;\n font-weight: 600;\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n background: #00a651;\n color: white;\n transition:\n background 0.2s,\n opacity 0.2s;\n}\n\n.pesafy-payment-btn:hover:not(:disabled) {\n background: #008f45;\n}\n\n.pesafy-payment-btn:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.pesafy-payment-btn-loading {\n opacity: 0.9;\n}\n\n.pesafy-payment-form {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n max-width: 24rem;\n}\n\n.pesafy-payment-form-field {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n}\n\n.pesafy-payment-form-field label {\n font-size: 0.875rem;\n font-weight: 500;\n}\n\n.pesafy-payment-form-field input {\n padding: 0.5rem 0.75rem;\n font-size: 1rem;\n border: 1px solid #d1d5db;\n border-radius: 0.375rem;\n}\n\n.pesafy-payment-form-field input:focus {\n outline: none;\n border-color: #00a651;\n box-shadow: 0 0 0 2px rgba(0, 166, 81, 0.2);\n}\n\n.pesafy-payment-form-submit {\n padding: 0.75rem 1.5rem;\n font-size: 1rem;\n font-weight: 600;\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n background: #00a651;\n color: white;\n margin-top: 0.5rem;\n}\n\n.pesafy-payment-form-submit:hover:not(:disabled) {\n background: #008f45;\n}\n\n.pesafy-payment-form-submit:disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.pesafy-qrcode {\n display: block;\n}\n\n.pesafy-payment-status {\n padding: 0.75rem 1rem;\n border-radius: 0.375rem;\n font-size: 0.875rem;\n}\n\n.pesafy-payment-status--pending {\n background: #fef3c7;\n color: #92400e;\n}\n\n.pesafy-payment-status--success {\n background: #d1fae5;\n color: #065f46;\n}\n\n.pesafy-payment-status--error {\n background: #fee2e2;\n color: #991b1b;\n}\n"],"mappings":";AAEA,CAAC;AACC,WAAS;AACT,eAAa;AACb,mBAAiB;AACjB,WAAS,QAAQ;AACjB,aAAW;AACX,eAAa;AACb,UAAQ;AACR,iBAAe;AACf,UAAQ;AACR,cAAY;AACZ,SAAO;AACP,cACE,WAAW,IAAI,EACf,QAAQ;AACZ;AAEA,CAjBC,kBAiBkB,MAAM,KAAK;AAC5B,cAAY;AACd;AAEA,CArBC,kBAqBkB;AACjB,WAAS;AACT,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACL,aAAW;AACb;AAEA,CAAC;AACC,WAAS;AACT,kBAAgB;AAChB,OAAK;AACP;AAEA,CANC,0BAM0B;AACzB,aAAW;AACX,eAAa;AACf;AAEA,CAXC,0BAW0B;AACzB,WAAS,OAAO;AAChB,aAAW;AACX,UAAQ,IAAI,MAAM;AAClB,iBAAe;AACjB;AAEA,CAlBC,0BAkB0B,KAAK;AAC9B,WAAS;AACT,gBAAc;AACd,cAAY,EAAE,EAAE,EAAE,IAAI,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;AACzC;AAEA,CAAC;AACC,WAAS,QAAQ;AACjB,aAAW;AACX,eAAa;AACb,UAAQ;AACR,iBAAe;AACf,UAAQ;AACR,cAAY;AACZ,SAAO;AACP,cAAY;AACd;AAEA,CAZC,0BAY0B,MAAM,KAAK;AACpC,cAAY;AACd;AAEA,CAhBC,0BAgB0B;AACzB,WAAS;AACT,UAAQ;AACV;AAEA,CAAC;AACC,WAAS;AACX;AAEA,CAAC;AACC,WAAS,QAAQ;AACjB,iBAAe;AACf,aAAW;AACb;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;AAEA,CAAC;AACC,cAAY;AACZ,SAAO;AACT;","names":[]}
|