@reevit/react 0.3.0 → 0.3.2
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 +15 -3
- package/dist/index.d.ts +15 -3
- package/dist/index.js +50 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +50 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -188,7 +188,13 @@ var ReevitAPIClient = class {
|
|
|
188
188
|
return this.request("GET", `/v1/payments/${paymentId}`);
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
|
-
* Confirms a payment after PSP callback
|
|
191
|
+
* Confirms a payment intent after PSP callback (public endpoint)
|
|
192
|
+
*/
|
|
193
|
+
async confirmPaymentIntent(paymentId, clientSecret) {
|
|
194
|
+
return this.request("POST", `/v1/payments/${paymentId}/confirm-intent?client_secret=${clientSecret}`);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Confirms a payment after PSP callback (authenticated endpoint)
|
|
192
198
|
*/
|
|
193
199
|
async confirmPayment(paymentId) {
|
|
194
200
|
return this.request("POST", `/v1/payments/${paymentId}/confirm`);
|
|
@@ -236,7 +242,7 @@ function reevitReducer(state, action) {
|
|
|
236
242
|
...state,
|
|
237
243
|
status: "ready",
|
|
238
244
|
paymentIntent: action.payload,
|
|
239
|
-
selectedMethod: action.payload.availableMethods?.length === 1 ? action.payload.availableMethods[0] :
|
|
245
|
+
selectedMethod: action.payload.availableMethods?.length === 1 ? action.payload.availableMethods[0] : null
|
|
240
246
|
};
|
|
241
247
|
case "INIT_ERROR":
|
|
242
248
|
return { ...state, status: "failed", error: action.payload };
|
|
@@ -273,6 +279,8 @@ function mapToPaymentIntent(response, config) {
|
|
|
273
279
|
status: response.status,
|
|
274
280
|
recommendedPsp: mapProviderToPsp(response.provider),
|
|
275
281
|
availableMethods: config.paymentMethods || ["card", "mobile_money"],
|
|
282
|
+
reference: response.reference || response.id,
|
|
283
|
+
// Use backend reference or fallback to ID
|
|
276
284
|
connectionId: response.connection_id,
|
|
277
285
|
provider: response.provider,
|
|
278
286
|
feeAmount: response.fee_amount,
|
|
@@ -375,8 +383,10 @@ function useReevit(options) {
|
|
|
375
383
|
if (!apiClient) {
|
|
376
384
|
throw new Error("API client not initialized");
|
|
377
385
|
}
|
|
378
|
-
const
|
|
386
|
+
const clientSecret = state.paymentIntent.clientSecret;
|
|
387
|
+
const { data, error } = clientSecret ? await apiClient.confirmPaymentIntent(state.paymentIntent.id, clientSecret) : await apiClient.confirmPayment(state.paymentIntent.id);
|
|
379
388
|
if (error) {
|
|
389
|
+
console.error("[useReevit] Confirmation error:", error);
|
|
380
390
|
dispatch({ type: "PROCESS_ERROR", payload: error });
|
|
381
391
|
onError?.(error);
|
|
382
392
|
return;
|
|
@@ -390,8 +400,9 @@ function useReevit(options) {
|
|
|
390
400
|
psp: state.paymentIntent.recommendedPsp,
|
|
391
401
|
pspReference: paymentData.pspReference || data?.provider_ref_id || "",
|
|
392
402
|
status: data?.status === "succeeded" ? "success" : "pending",
|
|
393
|
-
metadata: paymentData
|
|
403
|
+
metadata: { ...paymentData, backend_status: data?.status }
|
|
394
404
|
};
|
|
405
|
+
console.log("[useReevit] Process result:", result);
|
|
395
406
|
if (result.status === "success") {
|
|
396
407
|
dispatch({ type: "PROCESS_SUCCESS", payload: result });
|
|
397
408
|
onSuccess?.(result);
|
|
@@ -692,6 +703,7 @@ function PaystackBridge({
|
|
|
692
703
|
amount,
|
|
693
704
|
currency = "GHS",
|
|
694
705
|
reference,
|
|
706
|
+
accessCode,
|
|
695
707
|
metadata,
|
|
696
708
|
channels = ["card", "mobile_money"],
|
|
697
709
|
onSuccess,
|
|
@@ -702,30 +714,38 @@ function PaystackBridge({
|
|
|
702
714
|
const initialized = useRef(false);
|
|
703
715
|
const startPayment = useCallback(async () => {
|
|
704
716
|
try {
|
|
717
|
+
console.log("[PaystackBridge] Starting payment", {
|
|
718
|
+
hasPublicKey: !!publicKey,
|
|
719
|
+
email,
|
|
720
|
+
amount,
|
|
721
|
+
reference,
|
|
722
|
+
hasAccessCode: !!accessCode
|
|
723
|
+
});
|
|
705
724
|
if (!publicKey) {
|
|
706
725
|
throw new Error("Paystack public key is required but was empty");
|
|
707
726
|
}
|
|
708
|
-
if (!email) {
|
|
709
|
-
throw new Error("Email is required for Paystack payments");
|
|
727
|
+
if (!email && !accessCode) {
|
|
728
|
+
throw new Error("Email is required for Paystack payments when no access code is provided");
|
|
710
729
|
}
|
|
711
|
-
if (!amount
|
|
712
|
-
throw new Error("Valid amount is required for Paystack payments");
|
|
730
|
+
if (!amount && !accessCode) {
|
|
731
|
+
throw new Error("Valid amount is required for Paystack payments when no access code is provided");
|
|
713
732
|
}
|
|
714
733
|
await loadPaystackScript();
|
|
715
734
|
if (!window.PaystackPop) {
|
|
716
735
|
throw new Error("Paystack script loaded but PaystackPop not available");
|
|
717
736
|
}
|
|
718
|
-
const
|
|
737
|
+
const setupConfig = {
|
|
719
738
|
key: publicKey,
|
|
720
739
|
email,
|
|
721
740
|
phone,
|
|
722
741
|
amount,
|
|
723
|
-
// Paystack expects amount in kobo/pesewas (smallest unit)
|
|
724
742
|
currency,
|
|
725
743
|
ref: reference,
|
|
744
|
+
access_code: accessCode,
|
|
726
745
|
metadata,
|
|
727
746
|
channels,
|
|
728
747
|
callback: (response) => {
|
|
748
|
+
console.log("[PaystackBridge] Callback received", response);
|
|
729
749
|
let usedMethod = "card";
|
|
730
750
|
if (channels && channels.length === 1) {
|
|
731
751
|
usedMethod = channels[0];
|
|
@@ -733,22 +753,31 @@ function PaystackBridge({
|
|
|
733
753
|
usedMethod = "mobile_money";
|
|
734
754
|
}
|
|
735
755
|
const result = {
|
|
736
|
-
paymentId: response.
|
|
756
|
+
paymentId: response.reference,
|
|
757
|
+
// Use the reference as paymentId because we set it to Reevit's UUID
|
|
737
758
|
reference: response.reference,
|
|
738
759
|
amount,
|
|
739
760
|
currency,
|
|
740
761
|
paymentMethod: usedMethod,
|
|
741
762
|
psp: "paystack",
|
|
742
|
-
pspReference: response.
|
|
763
|
+
pspReference: response.transaction,
|
|
764
|
+
// Paystack's internal transaction ID
|
|
743
765
|
status: response.status === "success" ? "success" : "pending",
|
|
744
|
-
metadata: {
|
|
766
|
+
metadata: {
|
|
767
|
+
...response,
|
|
768
|
+
trxref: response.trxref,
|
|
769
|
+
paystack_transaction_id: response.transaction,
|
|
770
|
+
paystack_trans: response.trans
|
|
771
|
+
}
|
|
745
772
|
};
|
|
746
773
|
onSuccess(result);
|
|
747
774
|
},
|
|
748
775
|
onClose: () => {
|
|
776
|
+
console.log("[PaystackBridge] Modal closed");
|
|
749
777
|
onClose();
|
|
750
778
|
}
|
|
751
|
-
}
|
|
779
|
+
};
|
|
780
|
+
const handler = window.PaystackPop.setup(setupConfig);
|
|
752
781
|
handler.openIframe();
|
|
753
782
|
} catch (err) {
|
|
754
783
|
const errorMessage = err instanceof Error ? err.message : "Failed to initialize Paystack";
|
|
@@ -760,7 +789,7 @@ function PaystackBridge({
|
|
|
760
789
|
};
|
|
761
790
|
onError(error);
|
|
762
791
|
}
|
|
763
|
-
}, [publicKey, email, amount, currency, reference, metadata, channels, onSuccess, onError, onClose]);
|
|
792
|
+
}, [publicKey, email, amount, currency, reference, accessCode, metadata, channels, onSuccess, onError, onClose]);
|
|
764
793
|
useEffect(() => {
|
|
765
794
|
if (autoStart && !initialized.current) {
|
|
766
795
|
initialized.current = true;
|
|
@@ -863,10 +892,10 @@ function ReevitCheckout({
|
|
|
863
892
|
}
|
|
864
893
|
}, [isOpen, status, initialize, initialPaymentIntent]);
|
|
865
894
|
useEffect(() => {
|
|
866
|
-
if (isOpen &&
|
|
867
|
-
if (selectedMethod === "card"
|
|
895
|
+
if (isOpen && selectedMethod && paymentIntent && !showPSPBridge) {
|
|
896
|
+
if (selectedMethod === "card") {
|
|
868
897
|
setShowPSPBridge(true);
|
|
869
|
-
} else if (selectedMethod === "mobile_money" &&
|
|
898
|
+
} else if (selectedMethod === "mobile_money" && (momoData?.phone || phone)) {
|
|
870
899
|
setShowPSPBridge(true);
|
|
871
900
|
}
|
|
872
901
|
}
|
|
@@ -930,10 +959,10 @@ function ReevitCheckout({
|
|
|
930
959
|
formatAmount(amount, currency)
|
|
931
960
|
] }) : null;
|
|
932
961
|
const renderContent = () => {
|
|
933
|
-
if (status === "loading") {
|
|
962
|
+
if (status === "loading" || status === "processing") {
|
|
934
963
|
return /* @__PURE__ */ jsxs("div", { className: "reevit-loading", children: [
|
|
935
964
|
/* @__PURE__ */ jsx("div", { className: "reevit-spinner" }),
|
|
936
|
-
/* @__PURE__ */ jsx("p", { children: "Preparing checkout..." })
|
|
965
|
+
/* @__PURE__ */ jsx("p", { children: status === "loading" ? "Preparing checkout..." : "Processing payment..." })
|
|
937
966
|
] });
|
|
938
967
|
}
|
|
939
968
|
if (status === "success" && result) {
|
|
@@ -965,6 +994,7 @@ function ReevitCheckout({
|
|
|
965
994
|
amount: paymentIntent?.amount ?? amount,
|
|
966
995
|
currency: paymentIntent?.currency ?? currency,
|
|
967
996
|
reference,
|
|
997
|
+
accessCode: paymentIntent?.clientSecret,
|
|
968
998
|
metadata: {
|
|
969
999
|
...metadata,
|
|
970
1000
|
// Override with correct payment intent ID for webhook routing
|