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.
@@ -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":"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","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":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,2 @@
1
+
2
+ export { }