@reevit/vue 0.2.5 → 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.
@@ -11,6 +11,7 @@ type __VLS_Props = {
11
11
  theme?: ReevitTheme;
12
12
  isOpen?: boolean;
13
13
  apiBaseUrl?: string;
14
+ initialPaymentIntent?: any;
14
15
  };
15
16
  declare function __VLS_template(): {
16
17
  attrs: Partial<{}>;
@@ -1 +1 @@
1
- {"version":3,"file":"ReevitCheckout.vue.d.ts","sourceRoot":"","sources":["../../src/components/ReevitCheckout.vue"],"names":[],"mappings":"AAyPA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,GAAG,cAAc,GAAG,eAAe,CAAC,EAAE,CAAC;IAC/D,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAqIF,iBAAS,cAAc;WAqNT,OAAO,IAA6B;;;;;YAXrB,GAAG;+BACG,GAAG;;;;EAerC;AAuBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;6FAQnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAQpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"ReevitCheckout.vue.d.ts","sourceRoot":"","sources":["../../src/components/ReevitCheckout.vue"],"names":[],"mappings":"AAoQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD,KAAK,WAAW,GAAG;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,GAAG,cAAc,GAAG,eAAe,CAAC,EAAE,CAAC;IAC/D,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oBAAoB,CAAC,EAAE,GAAG,CAAC;CAC5B,CAAC;AA+IF,iBAAS,cAAc;WAqNT,OAAO,IAA6B;;;;;YAXrB,GAAG;+BACG,GAAG;;;;EAerC;AAuBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;6FAQnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAQpG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -12,11 +12,13 @@ export declare function useReevit(options: UseReevitOptions): {
12
12
  paymentIntent: Readonly<import('vue').Ref<{
13
13
  readonly id: string;
14
14
  readonly clientSecret: string;
15
+ readonly pspPublicKey?: string | undefined;
15
16
  readonly amount: number;
16
17
  readonly currency: string;
17
18
  readonly status: "pending" | "processing" | "succeeded" | "failed" | "cancelled";
18
19
  readonly recommendedPsp: PSPType;
19
20
  readonly availableMethods: readonly PaymentMethod[];
21
+ readonly reference?: string | undefined;
20
22
  readonly connectionId?: string | undefined;
21
23
  readonly provider?: string | undefined;
22
24
  readonly feeAmount?: number | undefined;
@@ -28,11 +30,13 @@ export declare function useReevit(options: UseReevitOptions): {
28
30
  } | null, {
29
31
  readonly id: string;
30
32
  readonly clientSecret: string;
33
+ readonly pspPublicKey?: string | undefined;
31
34
  readonly amount: number;
32
35
  readonly currency: string;
33
36
  readonly status: "pending" | "processing" | "succeeded" | "failed" | "cancelled";
34
37
  readonly recommendedPsp: PSPType;
35
38
  readonly availableMethods: readonly PaymentMethod[];
39
+ readonly reference?: string | undefined;
36
40
  readonly connectionId?: string | undefined;
37
41
  readonly provider?: string | undefined;
38
42
  readonly feeAmount?: number | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"useReevit.d.ts","sourceRoot":"","sources":["../../src/composables/useReevit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAKjB,KAAK,OAAO,EACb,MAAM,cAAc,CAAC;AAEtB,UAAU,gBAAgB;IACxB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAqCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BA0Bd,aAAa;2BA8ClB,aAAa;kCAKA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gCA6CzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;4BAKjC,YAAY;;;;;;;EAgE5C"}
1
+ {"version":3,"file":"useReevit.d.ts","sourceRoot":"","sources":["../../src/composables/useReevit.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAKjB,KAAK,OAAO,EACb,MAAM,cAAc,CAAC;AAEtB,UAAU,gBAAgB;IACxB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAwCd,aAAa;2BA8ClB,aAAa;kCAKA,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gCA8DzB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;4BAKjC,YAAY;;;;;;;EAgE5C"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),u=require("@reevit/core");function Q(t){const a=t.toLowerCase();return a.includes("paystack")?"paystack":a.includes("hubtel")?"hubtel":a.includes("flutterwave")?"flutterwave":"paystack"}function W(t,a){return{id:t.id,clientSecret:t.client_secret,amount:t.amount,currency:t.currency,status:t.status,recommendedPsp:Q(t.provider),availableMethods:a.paymentMethods||["card","mobile_money"],connectionId:t.connection_id,provider:t.provider,feeAmount:t.fee_amount,feeCurrency:t.fee_currency,netAmount:t.net_amount,metadata:a.metadata}}function D(t){const{config:a,onSuccess:n,onError:l,onClose:p,onStateChange:c,apiBaseUrl:i}=t,o=e.ref(u.createInitialState()),k=new u.ReevitAPIClient({publicKey:a.publicKey,baseUrl:i}),m=s=>{o.value=u.reevitReducer(o.value,s)};e.watch(()=>o.value.status,s=>{c?.(s)});const y=async s=>{m({type:"INIT_START"});try{const r=a.reference||u.generateReference(),d=u.detectCountryFromCurrency(a.currency),M=s||a.paymentMethods?.[0]||"card",{data:O,error:T}=await k.createPaymentIntent({...a,reference:r},M,d);if(T){m({type:"INIT_ERROR",payload:T}),l?.(T);return}if(!O){const $={code:"INIT_FAILED",message:"No data received from API",recoverable:!0};m({type:"INIT_ERROR",payload:$}),l?.($);return}const J=W(O,{...a,reference:r});m({type:"INIT_SUCCESS",payload:J})}catch(r){const d={code:"INIT_FAILED",message:r instanceof Error?r.message:"Failed to initialize checkout",recoverable:!0,originalError:r};m({type:"INIT_ERROR",payload:d}),l?.(d)}},h=s=>{m({type:"SELECT_METHOD",payload:s})},b=async s=>{if(!(!o.value.paymentIntent||!o.value.selectedMethod)){m({type:"PROCESS_START"});try{const{data:r,error:d}=await k.confirmPayment(o.value.paymentIntent.id);if(d){m({type:"PROCESS_ERROR",payload:d}),l?.(d);return}const M={paymentId:o.value.paymentIntent.id,reference:s.reference||o.value.paymentIntent.metadata?.reference||"",amount:o.value.paymentIntent.amount,currency:o.value.paymentIntent.currency,paymentMethod:o.value.selectedMethod,psp:o.value.paymentIntent.recommendedPsp,pspReference:s.pspReference||r?.provider_ref_id||"",status:"success",metadata:s};m({type:"PROCESS_SUCCESS",payload:M}),n?.(M)}catch(r){const d={code:"PAYMENT_FAILED",message:r instanceof Error?r.message:"Payment failed",recoverable:!0,originalError:r};m({type:"PROCESS_ERROR",payload:d}),l?.(d)}}},I=async s=>{await b(s)},V=s=>{m({type:"PROCESS_ERROR",payload:s}),l?.(s)},f=()=>{m({type:"RESET"})},C=async()=>{if(o.value.paymentIntent&&o.value.status!=="success")try{await k.cancelPaymentIntent(o.value.paymentIntent.id)}catch{}m({type:"CLOSE"}),p?.()},E=e.computed(()=>o.value.status),R=e.computed(()=>o.value.paymentIntent),N=e.computed(()=>o.value.selectedMethod),B=e.computed(()=>o.value.error),v=e.computed(()=>o.value.result),_=e.computed(()=>o.value.status==="loading"||o.value.status==="processing"),S=e.computed(()=>o.value.status==="ready"||o.value.status==="method_selected"||o.value.status==="processing"),P=e.computed(()=>o.value.status==="success"),g=e.computed(()=>o.value.error?.recoverable??!1);return{status:e.readonly(E),paymentIntent:e.readonly(R),selectedMethod:e.readonly(N),error:e.readonly(B),result:e.readonly(v),initialize:y,selectMethod:h,processPayment:b,handlePspSuccess:I,handlePspError:V,reset:f,close:C,isLoading:e.readonly(_),isReady:e.readonly(S),isComplete:e.readonly(P),canRetry:e.readonly(g)}}const X={class:"reevit-method-selector"},Z={class:"reevit-amount-display"},ee={class:"reevit-methods-grid"},te=["onClick"],ne={class:"reevit-method-icon"},oe={class:"reevit-method-info"},re={class:"reevit-method-name"},ae={class:"reevit-method-description"},se={class:"reevit-method-radio"},le={key:0,class:"reevit-radio-inner"},j=e.defineComponent({__name:"PaymentMethodSelector",props:{methods:{},selected:{},amount:{},currency:{}},emits:["select"],setup(t,{emit:a}){const n=t,l=a,p=e.computed(()=>[{id:"card",name:"Card",description:"Visa, Mastercard, Maestro",icon:"💳"},{id:"mobile_money",name:"Mobile Money",description:"MTN, Vodafone, AirtelTigo",icon:"📱"},{id:"bank_transfer",name:"Bank Transfer",description:"Transfer directly from your bank",icon:"🏦"}].filter(c=>n.methods.includes(c.id)));return(c,i)=>(e.openBlock(),e.createElementBlock("div",X,[i[0]||(i[0]=e.createElementVNode("h3",{class:"reevit-section-title"},"Select Payment Method",-1)),e.createElementVNode("p",Z," Pay "+e.toDisplayString(e.unref(u.formatAmount)(t.amount,t.currency)),1),e.createElementVNode("div",ee,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(p.value,o=>(e.openBlock(),e.createElementBlock("button",{key:o.id,type:"button",class:e.normalizeClass(e.unref(u.cn)("reevit-method-card",t.selected===o.id&&"reevit-method-card--selected")),onClick:k=>l("select",o.id)},[e.createElementVNode("span",ne,e.toDisplayString(o.icon),1),e.createElementVNode("div",oe,[e.createElementVNode("span",re,e.toDisplayString(o.name),1),e.createElementVNode("span",ae,e.toDisplayString(o.description),1)]),e.createElementVNode("div",se,[t.selected===o.id?(e.openBlock(),e.createElementBlock("div",le)):e.createCommentVNode("",!0)])],10,te))),128))])]))}}),ce={class:"reevit-form-group"},ie=["disabled"],de={class:"reevit-network-selector"},ue={class:"reevit-networks-grid"},me=["onClick","disabled"],pe={key:0,class:"reevit-error-message"},ye=["disabled"],ve={key:0,class:"reevit-spinner"},he={key:1},A=e.defineComponent({__name:"MobileMoneyForm",props:{initialPhone:{},loading:{type:Boolean}},emits:["submit"],setup(t,{emit:a}){const n=t,l=a,p=e.ref(n.initialPhone||""),c=e.ref(null),i=e.ref(null);e.watch(p,m=>{const y=u.detectNetwork(m);y&&(c.value=y),i.value&&(i.value=null)});const o=()=>{if(!u.validatePhone(p.value)){i.value="Please enter a valid phone number";return}if(!c.value){i.value="Please select your mobile network";return}l("submit",{phone:p.value,network:c.value})},k=[{id:"mtn",name:"MTN",color:"#FFCC00"},{id:"vodafone",name:"Vodafone",color:"#E60000"},{id:"airteltigo",name:"AirtelTigo",color:"#005596"}];return(m,y)=>(e.openBlock(),e.createElementBlock("form",{class:"reevit-momo-form",onSubmit:e.withModifiers(o,["prevent"])},[e.createElementVNode("div",ce,[y[1]||(y[1]=e.createElementVNode("label",{class:"reevit-label",for:"reevit-phone"},"Phone Number",-1)),e.withDirectives(e.createElementVNode("input",{id:"reevit-phone","onUpdate:modelValue":y[0]||(y[0]=h=>p.value=h),type:"tel",class:e.normalizeClass(["reevit-input",{"reevit-input--error":i.value&&!e.unref(u.validatePhone)(p.value)}]),placeholder:"e.g. 024 123 4567",disabled:t.loading,autocomplete:"tel"},null,10,ie),[[e.vModelText,p.value]])]),e.createElementVNode("div",de,[y[2]||(y[2]=e.createElementVNode("label",{class:"reevit-label"},"Select Network",-1)),e.createElementVNode("div",ue,[(e.openBlock(),e.createElementBlock(e.Fragment,null,e.renderList(k,h=>e.createElementVNode("button",{key:h.id,type:"button",class:e.normalizeClass(e.unref(u.cn)("reevit-network-btn",c.value===h.id&&"reevit-network-btn--selected")),onClick:b=>c.value=h.id,disabled:t.loading},[e.createElementVNode("div",{class:"reevit-network-dot",style:e.normalizeStyle({backgroundColor:h.color})},null,4),e.createTextVNode(" "+e.toDisplayString(h.name),1)],10,me)),64))])]),i.value?(e.openBlock(),e.createElementBlock("p",pe,e.toDisplayString(i.value),1)):e.createCommentVNode("",!0),e.createElementVNode("button",{type:"submit",class:"reevit-submit-btn",disabled:t.loading||!p.value},[t.loading?(e.openBlock(),e.createElementBlock("span",ve)):(e.openBlock(),e.createElementBlock("span",he,"Continue"))],8,ye),y[3]||(y[3]=e.createElementVNode("p",{class:"reevit-secure-text"}," 🔒 Secure mobile money payment via Reevit ",-1))],32))}}),F=new Map;function w(t,a){const n=F.get(a);if(n)return n;const l=new Promise((p,c)=>{if(document.getElementById(a)){p();return}const i=document.createElement("script");i.id=a,i.src=t,i.async=!0,i.onload=()=>p(),i.onerror=()=>c(new Error(`Failed to load ${a} script`)),document.head.appendChild(i)});return F.set(a,l),l}function K(){return w("https://js.paystack.co/v1/inline.js","paystack-script")}function L(){return w("https://checkout.hubtel.com/js/hubtel-checkout.js","hubtel-script")}function z(){return w("https://checkout.flutterwave.com/v3.js","flutterwave-script")}function U(){return w("https://js.stripe.com/v3/","stripe-script")}function x(){return w("https://sdk.monnify.com/plugin/monnify.js","monnify-script")}async function H(t){if(await K(),!window.PaystackPop)throw new Error("Paystack script not loaded");window.PaystackPop.setup({key:t.key,email:t.email,amount:t.amount,currency:t.currency,ref:t.ref,metadata:t.metadata,callback:t.onSuccess,onClose:t.onClose}).openIframe()}async function q(t){if(await L(),!window.HubtelCheckout)throw new Error("Hubtel script not loaded");window.HubtelCheckout.initPay({clientId:t.clientId,purchaseDescription:t.purchaseDescription,amount:t.amount,callbackUrl:t.callbackUrl,customerPhone:t.customerPhone,customerEmail:t.customerEmail,onSuccess:t.onSuccess,onClose:t.onClose})}async function Y(t){if(await z(),!window.FlutterwaveCheckout)throw new Error("Flutterwave script not loaded");window.FlutterwaveCheckout({public_key:t.public_key,tx_ref:t.tx_ref,amount:t.amount,currency:t.currency,customer:t.customer,payment_options:t.payment_options,customizations:t.customizations,callback:t.callback,onclose:t.onclose})}async function G(t){if(await U(),!window.Stripe)throw new Error("Stripe.js not loaded");return window.Stripe(t)}async function ke(t){const n=await(await G(t.publishableKey)).confirmPayment({elements:t.elements,clientSecret:t.clientSecret,redirect:"if_required"});n.error?t.onError({message:n.error.message||"Payment failed"}):n.paymentIntent&&t.onSuccess({paymentIntentId:n.paymentIntent.id,status:n.paymentIntent.status})}async function be(t){if(await x(),!window.MonnifySDK)throw new Error("Monnify SDK not loaded");window.MonnifySDK.initialize({amount:t.amount,currency:t.currency,reference:t.reference,customerName:t.customerName,customerEmail:t.customerEmail,customerMobileNumber:t.customerPhone,apiKey:t.apiKey,contractCode:t.contractCode,paymentDescription:t.paymentDescription||"Payment",isTestMode:t.isTestMode??!1,metadata:t.metadata,onComplete:a=>{a.status==="SUCCESS"?t.onSuccess({transactionReference:a.transactionReference,paymentReference:a.paymentReference,...a}):t.onError?.({message:a.message||"Payment failed"})},onClose:t.onClose})}async function fe(t,a){t.onInitiated();try{const n=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phone_number:t.phoneNumber,amount:t.amount,reference:t.reference,description:t.description})});if(!n.ok){const c=(await n.json().catch(()=>({}))).message||"Failed to initiate M-Pesa payment";return t.onError({message:c}),{status:"failed",message:c}}const l=await n.json();return{status:"initiated",message:"Please check your phone and enter your M-Pesa PIN to complete the payment.",transactionId:l.checkout_request_id||l.transaction_id}}catch(n){const l=n instanceof Error?n.message:"Network error";return t.onError({message:l}),{status:"failed",message:l}}}const Ee=["disabled"],Se={key:0,class:"reevit-spinner"},Pe={class:"reevit-modal-body"},we={key:0,class:"reevit-loading-state"},Ce={key:1,class:"reevit-error-state"},Ne={key:2,class:"reevit-success-state"},_e={key:1,class:"reevit-method-form-container"},Me={key:2,class:"reevit-card-info"},Ie=["disabled"],Ve={key:0,class:"reevit-spinner"},Re={key:1},Be=e.defineComponent({__name:"ReevitCheckout",props:{publicKey:{},amount:{},currency:{},email:{},phone:{},reference:{},metadata:{},paymentMethods:{},theme:{},isOpen:{type:Boolean},apiBaseUrl:{}},emits:["success","error","close"],setup(t,{emit:a}){const n=t,l=a,{status:p,paymentIntent:c,selectedMethod:i,error:o,isLoading:k,isReady:m,initialize:y,selectMethod:h,handlePspSuccess:b,handlePspError:I,close:V}=D({config:{publicKey:n.publicKey,amount:n.amount,currency:n.currency,email:n.email,phone:n.phone,reference:n.reference,metadata:n.metadata,paymentMethods:n.paymentMethods},apiBaseUrl:n.apiBaseUrl,onSuccess:s=>l("success",s),onError:s=>l("error",s),onClose:()=>l("close")}),f=e.ref(n.isOpen??!1);e.watch(()=>n.isOpen,s=>{s!==void 0&&(f.value=s)});const C=()=>{f.value=!0,c.value||y()},E=()=>{f.value=!1,V()},R=s=>{h(s)},N=async s=>{if(!c.value)return;const r=c.value.recommendedPsp;try{r==="paystack"?await H({key:n.publicKey,email:n.email||"",amount:n.amount,currency:n.currency,ref:c.value.id,onSuccess:d=>b(d),onClose:()=>{}}):r==="hubtel"?await q({clientId:n.publicKey,purchaseDescription:`Payment for ${n.amount} ${n.currency}`,amount:n.amount,customerPhone:s?.phone||n.phone,customerEmail:n.email,onSuccess:d=>b(d),onClose:()=>{}}):r==="flutterwave"&&await Y({public_key:n.publicKey,tx_ref:c.value.id,amount:n.amount,currency:n.currency,customer:{email:n.email||"",phone_number:s?.phone||n.phone},callback:d=>b(d),onclose:()=>{}})}catch(d){I({code:"BRIDGE_ERROR",message:d instanceof Error?d.message:"Failed to open payment gateway"})}},B=e.computed(()=>u.createThemeVariables(n.theme||{}));e.watch(f,s=>{s?document.body.style.overflow="hidden":document.body.style.overflow=""}),e.onUnmounted(()=>{document.body.style.overflow=""});const v=e.computed(()=>p.value),_=e.computed(()=>o.value),S=e.computed(()=>i.value),P=e.computed(()=>k.value),g=e.computed(()=>m.value);return(s,r)=>(e.openBlock(),e.createElementBlock("div",{class:"reevit-sdk-container",style:e.normalizeStyle(B.value)},[e.renderSlot(s.$slots,"default",{open:C,isLoading:P.value},()=>[e.createElementVNode("button",{type:"button",class:"reevit-pay-button",onClick:C,disabled:P.value},[P.value?(e.openBlock(),e.createElementBlock("span",Se)):e.renderSlot(s.$slots,"button-text",{key:1},()=>[r[1]||(r[1]=e.createTextVNode("Pay Now",-1))])],8,Ee)]),(e.openBlock(),e.createBlock(e.Teleport,{to:"body"},[f.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"reevit-modal-overlay",onClick:e.withModifiers(E,["self"])},[e.createElementVNode("div",{class:e.normalizeClass(["reevit-modal-content",{"reevit-modal--dark":n.theme?.darkMode}])},[e.createElementVNode("button",{class:"reevit-modal-close",onClick:E,"aria-label":"Close"}," × "),r[9]||(r[9]=e.createElementVNode("div",{class:"reevit-modal-header"},[e.createElementVNode("img",{src:"https://i.imgur.com/bzUR5Lm.png",alt:"Reevit",class:"reevit-modal__logo"})],-1)),e.createElementVNode("div",Pe,[v.value==="loading"?(e.openBlock(),e.createElementBlock("div",we,[...r[2]||(r[2]=[e.createElementVNode("div",{class:"reevit-spinner reevit-spinner--large"},null,-1),e.createElementVNode("p",null,"Initializing payment...",-1)])])):v.value==="failed"&&_.value?(e.openBlock(),e.createElementBlock("div",Ce,[r[3]||(r[3]=e.createElementVNode("div",{class:"reevit-error-icon"},"⚠️",-1)),r[4]||(r[4]=e.createElementVNode("h3",null,"Payment Failed",-1)),e.createElementVNode("p",null,e.toDisplayString(_.value.message),1),e.createElementVNode("button",{class:"reevit-retry-btn",onClick:r[0]||(r[0]=d=>e.unref(y)())},"Retry")])):v.value==="success"?(e.openBlock(),e.createElementBlock("div",Ne,[r[5]||(r[5]=e.createElementVNode("div",{class:"reevit-success-icon"},"✅",-1)),r[6]||(r[6]=e.createElementVNode("h3",null,"Payment Successful",-1)),r[7]||(r[7]=e.createElementVNode("p",null,"Thank you for your payment.",-1)),e.createElementVNode("button",{class:"reevit-done-btn",onClick:E},"Done")])):g.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:3},[v.value==="ready"||v.value==="method_selected"||v.value==="processing"?(e.openBlock(),e.createBlock(j,{key:0,methods:n.paymentMethods||["card","mobile_money"],selected:S.value,amount:n.amount,currency:n.currency,onSelect:R},null,8,["methods","selected","amount","currency"])):e.createCommentVNode("",!0),(v.value==="method_selected"||v.value==="processing")&&S.value==="mobile_money"?(e.openBlock(),e.createElementBlock("div",_e,[e.createVNode(A,{"initial-phone":n.phone,loading:v.value==="processing",onSubmit:N},null,8,["initial-phone","loading"])])):e.createCommentVNode("",!0),(v.value==="method_selected"||v.value==="processing")&&S.value==="card"?(e.openBlock(),e.createElementBlock("div",Me,[r[8]||(r[8]=e.createElementVNode("p",{class:"reevit-info-text"},"You will be redirected to our secure payment partner to complete your card payment.",-1)),e.createElementVNode("button",{class:"reevit-submit-btn",onClick:N,disabled:v.value==="processing"},[v.value==="processing"?(e.openBlock(),e.createElementBlock("span",Ve)):(e.openBlock(),e.createElementBlock("span",Re,"Proceed to Card Payment"))],8,Ie)])):e.createCommentVNode("",!0)],64)):e.createCommentVNode("",!0)]),r[10]||(r[10]=e.createElementVNode("div",{class:"reevit-modal-footer"},[e.createElementVNode("div",{class:"reevit-trust-badges"},[e.createElementVNode("span",null,"PCI DSS Compliant"),e.createElementVNode("span",null,"•"),e.createElementVNode("span",null,"SSL Secure")])],-1))],2)])):e.createCommentVNode("",!0)]))],4))}});Object.defineProperty(exports,"ReevitAPIClient",{enumerable:!0,get:()=>u.ReevitAPIClient});Object.defineProperty(exports,"cn",{enumerable:!0,get:()=>u.cn});Object.defineProperty(exports,"createReevitClient",{enumerable:!0,get:()=>u.createReevitClient});Object.defineProperty(exports,"detectCountryFromCurrency",{enumerable:!0,get:()=>u.detectCountryFromCurrency});Object.defineProperty(exports,"detectNetwork",{enumerable:!0,get:()=>u.detectNetwork});Object.defineProperty(exports,"formatAmount",{enumerable:!0,get:()=>u.formatAmount});Object.defineProperty(exports,"formatPhone",{enumerable:!0,get:()=>u.formatPhone});Object.defineProperty(exports,"validatePhone",{enumerable:!0,get:()=>u.validatePhone});exports.MobileMoneyForm=A;exports.PaymentMethodSelector=j;exports.ReevitCheckout=Be;exports.confirmStripePayment=ke;exports.createStripeInstance=G;exports.initiateMPesaSTKPush=fe;exports.loadFlutterwaveScript=z;exports.loadHubtelScript=L;exports.loadMonnifyScript=x;exports.loadPaystackScript=K;exports.loadStripeScript=U;exports.openFlutterwaveModal=Y;exports.openHubtelPopup=q;exports.openMonnifyModal=be;exports.openPaystackPopup=H;exports.useReevit=D;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("vue"),d=require("@reevit/core");function Q(t){const l=t.toLowerCase();return l.includes("paystack")?"paystack":l.includes("hubtel")?"hubtel":l.includes("flutterwave")?"flutterwave":"paystack"}function W(t,l){return{id:t.id,clientSecret:t.client_secret,pspPublicKey:t.psp_public_key,amount:t.amount,currency:t.currency,status:t.status,recommendedPsp:Q(t.provider),availableMethods:l.paymentMethods||["card","mobile_money"],reference:t.reference||l.reference,connectionId:t.connection_id,provider:t.provider,feeAmount:t.fee_amount,feeCurrency:t.fee_currency,netAmount:t.net_amount,metadata:l.metadata}}function F(t){const{config:l,onSuccess:n,onError:s,onClose:p,onStateChange:i,apiBaseUrl:u}=t,o=e.ref(d.createInitialState());if(l.initialPaymentIntent){const r=l.initialPaymentIntent;o.value={...o.value,status:"ready",paymentIntent:r,selectedMethod:r.availableMethods?.length===1?r.availableMethods[0]:null}}const k=new d.ReevitAPIClient({publicKey:l.publicKey,baseUrl:u}),m=r=>{o.value=d.reevitReducer(o.value,r)};e.watch(()=>o.value.status,r=>{i?.(r)});const y=async r=>{m({type:"INIT_START"});try{const a=l.reference||d.generateReference(),c=d.detectCountryFromCurrency(l.currency),_=r||l.paymentMethods?.[0]||"card",{data:f,error:O}=await k.createPaymentIntent({...l,reference:a},_,c);if(O){m({type:"INIT_ERROR",payload:O}),s?.(O);return}if(!f){const $={code:"INIT_FAILED",message:"No data received from API",recoverable:!0};m({type:"INIT_ERROR",payload:$}),s?.($);return}const J=W(f,{...l,reference:a});m({type:"INIT_SUCCESS",payload:J})}catch(a){const c={code:"INIT_FAILED",message:a instanceof Error?a.message:"Failed to initialize checkout",recoverable:!0,originalError:a};m({type:"INIT_ERROR",payload:c}),s?.(c)}},h=r=>{m({type:"SELECT_METHOD",payload:r})},E=async r=>{if(!(!o.value.paymentIntent||!o.value.selectedMethod)){m({type:"PROCESS_START"});try{let a;if(o.value.paymentIntent.clientSecret){const{data:_,error:f}=await k.confirmPaymentIntent(o.value.paymentIntent.id,o.value.paymentIntent.clientSecret);if(f){m({type:"PROCESS_ERROR",payload:f}),s?.(f);return}a=_}else{const{data:_,error:f}=await k.confirmPayment(o.value.paymentIntent.id);if(f){m({type:"PROCESS_ERROR",payload:f}),s?.(f);return}a=_}const c={paymentId:o.value.paymentIntent.id,reference:r.reference||o.value.paymentIntent.reference||o.value.paymentIntent.metadata?.reference||"",amount:o.value.paymentIntent.amount,currency:o.value.paymentIntent.currency,paymentMethod:o.value.selectedMethod,psp:o.value.paymentIntent.recommendedPsp,pspReference:r.pspReference||a?.provider_ref_id||"",status:"success",metadata:r};m({type:"PROCESS_SUCCESS",payload:c}),n?.(c)}catch(a){const c={code:"PAYMENT_FAILED",message:a instanceof Error?a.message:"Payment failed",recoverable:!0,originalError:a};m({type:"PROCESS_ERROR",payload:c}),s?.(c)}}},R=async r=>{await E(r)},V=r=>{m({type:"PROCESS_ERROR",payload:r}),s?.(r)},b=()=>{m({type:"RESET"})},I=async()=>{if(o.value.paymentIntent&&o.value.status!=="success")try{await k.cancelPaymentIntent(o.value.paymentIntent.id)}catch{}m({type:"CLOSE"}),p?.()},S=e.computed(()=>o.value.status),B=e.computed(()=>o.value.paymentIntent),P=e.computed(()=>o.value.selectedMethod),g=e.computed(()=>o.value.error),v=e.computed(()=>o.value.result),M=e.computed(()=>o.value.status==="loading"||o.value.status==="processing"),w=e.computed(()=>o.value.status==="ready"||o.value.status==="method_selected"||o.value.status==="processing"),C=e.computed(()=>o.value.status==="success"),T=e.computed(()=>o.value.error?.recoverable??!1);return{status:e.readonly(S),paymentIntent:e.readonly(B),selectedMethod:e.readonly(P),error:e.readonly(g),result:e.readonly(v),initialize:y,selectMethod:h,processPayment:E,handlePspSuccess:R,handlePspError:V,reset:b,close:I,isLoading:e.readonly(M),isReady:e.readonly(w),isComplete:e.readonly(C),canRetry:e.readonly(T)}}const X={class:"reevit-method-selector"},Z={class:"reevit-amount-display"},ee={class:"reevit-methods-grid"},te=["onClick"],ne={class:"reevit-method-icon"},oe={class:"reevit-method-info"},ae={class:"reevit-method-name"},re={class:"reevit-method-description"},le={class:"reevit-method-radio"},se={key:0,class:"reevit-radio-inner"},j=e.defineComponent({__name:"PaymentMethodSelector",props:{methods:{},selected:{},amount:{},currency:{}},emits:["select"],setup(t,{emit:l}){const n=t,s=l,p=e.computed(()=>[{id:"card",name:"Card",description:"Visa, Mastercard, Maestro",icon:"💳"},{id:"mobile_money",name:"Mobile Money",description:"MTN, Vodafone, AirtelTigo",icon:"📱"},{id:"bank_transfer",name:"Bank Transfer",description:"Transfer directly from your bank",icon:"🏦"}].filter(i=>n.methods.includes(i.id)));return(i,u)=>(e.openBlock(),e.createElementBlock("div",X,[u[0]||(u[0]=e.createElementVNode("h3",{class:"reevit-section-title"},"Select Payment Method",-1)),e.createElementVNode("p",Z," Pay "+e.toDisplayString(e.unref(d.formatAmount)(t.amount,t.currency)),1),e.createElementVNode("div",ee,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(p.value,o=>(e.openBlock(),e.createElementBlock("button",{key:o.id,type:"button",class:e.normalizeClass(e.unref(d.cn)("reevit-method-card",t.selected===o.id&&"reevit-method-card--selected")),onClick:k=>s("select",o.id)},[e.createElementVNode("span",ne,e.toDisplayString(o.icon),1),e.createElementVNode("div",oe,[e.createElementVNode("span",ae,e.toDisplayString(o.name),1),e.createElementVNode("span",re,e.toDisplayString(o.description),1)]),e.createElementVNode("div",le,[t.selected===o.id?(e.openBlock(),e.createElementBlock("div",se)):e.createCommentVNode("",!0)])],10,te))),128))])]))}}),ce={class:"reevit-form-group"},ie=["disabled"],ue={class:"reevit-network-selector"},de={class:"reevit-networks-grid"},me=["onClick","disabled"],pe={key:0,class:"reevit-error-message"},ye=["disabled"],ve={key:0,class:"reevit-spinner"},he={key:1},A=e.defineComponent({__name:"MobileMoneyForm",props:{initialPhone:{},loading:{type:Boolean}},emits:["submit"],setup(t,{emit:l}){const n=t,s=l,p=e.ref(n.initialPhone||""),i=e.ref(null),u=e.ref(null);e.watch(p,m=>{const y=d.detectNetwork(m);y&&(i.value=y),u.value&&(u.value=null)});const o=()=>{if(!d.validatePhone(p.value)){u.value="Please enter a valid phone number";return}if(!i.value){u.value="Please select your mobile network";return}s("submit",{phone:p.value,network:i.value})},k=[{id:"mtn",name:"MTN",color:"#FFCC00"},{id:"vodafone",name:"Vodafone",color:"#E60000"},{id:"airteltigo",name:"AirtelTigo",color:"#005596"}];return(m,y)=>(e.openBlock(),e.createElementBlock("form",{class:"reevit-momo-form",onSubmit:e.withModifiers(o,["prevent"])},[e.createElementVNode("div",ce,[y[1]||(y[1]=e.createElementVNode("label",{class:"reevit-label",for:"reevit-phone"},"Phone Number",-1)),e.withDirectives(e.createElementVNode("input",{id:"reevit-phone","onUpdate:modelValue":y[0]||(y[0]=h=>p.value=h),type:"tel",class:e.normalizeClass(["reevit-input",{"reevit-input--error":u.value&&!e.unref(d.validatePhone)(p.value)}]),placeholder:"e.g. 024 123 4567",disabled:t.loading,autocomplete:"tel"},null,10,ie),[[e.vModelText,p.value]])]),e.createElementVNode("div",ue,[y[2]||(y[2]=e.createElementVNode("label",{class:"reevit-label"},"Select Network",-1)),e.createElementVNode("div",de,[(e.openBlock(),e.createElementBlock(e.Fragment,null,e.renderList(k,h=>e.createElementVNode("button",{key:h.id,type:"button",class:e.normalizeClass(e.unref(d.cn)("reevit-network-btn",i.value===h.id&&"reevit-network-btn--selected")),onClick:E=>i.value=h.id,disabled:t.loading},[e.createElementVNode("div",{class:"reevit-network-dot",style:e.normalizeStyle({backgroundColor:h.color})},null,4),e.createTextVNode(" "+e.toDisplayString(h.name),1)],10,me)),64))])]),u.value?(e.openBlock(),e.createElementBlock("p",pe,e.toDisplayString(u.value),1)):e.createCommentVNode("",!0),e.createElementVNode("button",{type:"submit",class:"reevit-submit-btn",disabled:t.loading||!p.value},[t.loading?(e.openBlock(),e.createElementBlock("span",ve)):(e.openBlock(),e.createElementBlock("span",he,"Continue"))],8,ye),y[3]||(y[3]=e.createElementVNode("p",{class:"reevit-secure-text"}," 🔒 Secure mobile money payment via Reevit ",-1))],32))}}),D=new Map;function N(t,l){const n=D.get(l);if(n)return n;const s=new Promise((p,i)=>{if(document.getElementById(l)){p();return}const u=document.createElement("script");u.id=l,u.src=t,u.async=!0,u.onload=()=>p(),u.onerror=()=>i(new Error(`Failed to load ${l} script`)),document.head.appendChild(u)});return D.set(l,s),s}function K(){return N("https://js.paystack.co/v1/inline.js","paystack-script")}function L(){return N("https://checkout.hubtel.com/js/hubtel-checkout.js","hubtel-script")}function z(){return N("https://checkout.flutterwave.com/v3.js","flutterwave-script")}function U(){return N("https://js.stripe.com/v3/","stripe-script")}function x(){return N("https://sdk.monnify.com/plugin/monnify.js","monnify-script")}async function H(t){if(await K(),!window.PaystackPop)throw new Error("Paystack script not loaded");window.PaystackPop.setup({key:t.key,email:t.email,amount:t.amount,currency:t.currency,ref:t.ref,metadata:t.metadata,callback:t.onSuccess,onClose:t.onClose}).openIframe()}async function q(t){if(await L(),!window.HubtelCheckout)throw new Error("Hubtel script not loaded");window.HubtelCheckout.initPay({clientId:t.clientId,purchaseDescription:t.purchaseDescription,amount:t.amount,callbackUrl:t.callbackUrl,customerPhone:t.customerPhone,customerEmail:t.customerEmail,onSuccess:t.onSuccess,onClose:t.onClose})}async function Y(t){if(await z(),!window.FlutterwaveCheckout)throw new Error("Flutterwave script not loaded");window.FlutterwaveCheckout({public_key:t.public_key,tx_ref:t.tx_ref,amount:t.amount,currency:t.currency,customer:t.customer,payment_options:t.payment_options,customizations:t.customizations,callback:t.callback,onclose:t.onclose})}async function G(t){if(await U(),!window.Stripe)throw new Error("Stripe.js not loaded");return window.Stripe(t)}async function fe(t){const n=await(await G(t.publishableKey)).confirmPayment({elements:t.elements,clientSecret:t.clientSecret,redirect:"if_required"});n.error?t.onError({message:n.error.message||"Payment failed"}):n.paymentIntent&&t.onSuccess({paymentIntentId:n.paymentIntent.id,status:n.paymentIntent.status})}async function ke(t){if(await x(),!window.MonnifySDK)throw new Error("Monnify SDK not loaded");window.MonnifySDK.initialize({amount:t.amount,currency:t.currency,reference:t.reference,customerName:t.customerName,customerEmail:t.customerEmail,customerMobileNumber:t.customerPhone,apiKey:t.apiKey,contractCode:t.contractCode,paymentDescription:t.paymentDescription||"Payment",isTestMode:t.isTestMode??!1,metadata:t.metadata,onComplete:l=>{l.status==="SUCCESS"?t.onSuccess({transactionReference:l.transactionReference,paymentReference:l.paymentReference,...l}):t.onError?.({message:l.message||"Payment failed"})},onClose:t.onClose})}async function be(t,l){t.onInitiated();try{const n=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phone_number:t.phoneNumber,amount:t.amount,reference:t.reference,description:t.description})});if(!n.ok){const i=(await n.json().catch(()=>({}))).message||"Failed to initiate M-Pesa payment";return t.onError({message:i}),{status:"failed",message:i}}const s=await n.json();return{status:"initiated",message:"Please check your phone and enter your M-Pesa PIN to complete the payment.",transactionId:s.checkout_request_id||s.transaction_id}}catch(n){const s=n instanceof Error?n.message:"Network error";return t.onError({message:s}),{status:"failed",message:s}}}const Ee=["disabled"],Se={key:0,class:"reevit-spinner"},Pe={class:"reevit-modal-body"},we={key:0,class:"reevit-loading-state"},Ce={key:1,class:"reevit-error-state"},_e={key:2,class:"reevit-success-state"},Ne={key:1,class:"reevit-method-form-container"},Ie={key:2,class:"reevit-card-info"},Me=["disabled"],Re={key:0,class:"reevit-spinner"},Ve={key:1},Be=e.defineComponent({__name:"ReevitCheckout",props:{publicKey:{},amount:{},currency:{},email:{},phone:{},reference:{},metadata:{},paymentMethods:{},theme:{},isOpen:{type:Boolean},apiBaseUrl:{},initialPaymentIntent:{}},emits:["success","error","close"],setup(t,{emit:l}){const n=t,s=l,{status:p,paymentIntent:i,selectedMethod:u,error:o,isLoading:k,isReady:m,initialize:y,selectMethod:h,handlePspSuccess:E,handlePspError:R,close:V}=F({config:{publicKey:n.publicKey,amount:n.amount,currency:n.currency,email:n.email,phone:n.phone,reference:n.reference,metadata:n.metadata,paymentMethods:n.paymentMethods,initialPaymentIntent:n.initialPaymentIntent},apiBaseUrl:n.apiBaseUrl,onSuccess:r=>s("success",r),onError:r=>s("error",r),onClose:()=>s("close")}),b=e.ref(n.isOpen??!1);e.watch(()=>n.isOpen,r=>{r!==void 0&&(b.value=r)});const I=()=>{b.value=!0,!i.value&&p.value==="idle"&&y()};e.watch([b,i,u],([r,a,c])=>{r&&a&&c&&c==="card"&&P(null)});const S=()=>{b.value=!1,V()},B=r=>{h(r)},P=async r=>{if(!i.value)return;const a=i.value.recommendedPsp;try{a==="paystack"?await H({key:n.publicKey,email:n.email||"",amount:n.amount,currency:n.currency,ref:i.value.id,onSuccess:c=>E(c),onClose:()=>{}}):a==="hubtel"?await q({clientId:n.publicKey,purchaseDescription:`Payment for ${n.amount} ${n.currency}`,amount:n.amount,customerPhone:r?.phone||n.phone,customerEmail:n.email,onSuccess:c=>E(c),onClose:()=>{}}):a==="flutterwave"&&await Y({public_key:n.publicKey,tx_ref:i.value.id,amount:n.amount,currency:n.currency,customer:{email:n.email||"",phone_number:r?.phone||n.phone},callback:c=>E(c),onclose:()=>{}})}catch(c){R({code:"BRIDGE_ERROR",message:c instanceof Error?c.message:"Failed to open payment gateway"})}},g=e.computed(()=>d.createThemeVariables(n.theme||{}));e.watch(b,r=>{r?document.body.style.overflow="hidden":document.body.style.overflow=""}),e.onUnmounted(()=>{document.body.style.overflow=""});const v=e.computed(()=>p.value),M=e.computed(()=>o.value),w=e.computed(()=>u.value),C=e.computed(()=>k.value),T=e.computed(()=>m.value);return(r,a)=>(e.openBlock(),e.createElementBlock("div",{class:"reevit-sdk-container",style:e.normalizeStyle(g.value)},[e.renderSlot(r.$slots,"default",{open:I,isLoading:C.value},()=>[e.createElementVNode("button",{type:"button",class:"reevit-pay-button",onClick:I,disabled:C.value},[C.value?(e.openBlock(),e.createElementBlock("span",Se)):e.renderSlot(r.$slots,"button-text",{key:1},()=>[a[1]||(a[1]=e.createTextVNode("Pay Now",-1))])],8,Ee)]),(e.openBlock(),e.createBlock(e.Teleport,{to:"body"},[b.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"reevit-modal-overlay",onClick:e.withModifiers(S,["self"])},[e.createElementVNode("div",{class:e.normalizeClass(["reevit-modal-content",{"reevit-modal--dark":n.theme?.darkMode}])},[e.createElementVNode("button",{class:"reevit-modal-close",onClick:S,"aria-label":"Close"}," × "),a[9]||(a[9]=e.createElementVNode("div",{class:"reevit-modal-header"},[e.createElementVNode("img",{src:"https://i.imgur.com/bzUR5Lm.png",alt:"Reevit",class:"reevit-modal__logo"})],-1)),e.createElementVNode("div",Pe,[v.value==="loading"?(e.openBlock(),e.createElementBlock("div",we,[...a[2]||(a[2]=[e.createElementVNode("div",{class:"reevit-spinner reevit-spinner--large"},null,-1),e.createElementVNode("p",null,"Initializing payment...",-1)])])):v.value==="failed"&&M.value?(e.openBlock(),e.createElementBlock("div",Ce,[a[3]||(a[3]=e.createElementVNode("div",{class:"reevit-error-icon"},"⚠️",-1)),a[4]||(a[4]=e.createElementVNode("h3",null,"Payment Failed",-1)),e.createElementVNode("p",null,e.toDisplayString(M.value.message),1),e.createElementVNode("button",{class:"reevit-retry-btn",onClick:a[0]||(a[0]=c=>e.unref(y)())},"Retry")])):v.value==="success"?(e.openBlock(),e.createElementBlock("div",_e,[a[5]||(a[5]=e.createElementVNode("div",{class:"reevit-success-icon"},"✅",-1)),a[6]||(a[6]=e.createElementVNode("h3",null,"Payment Successful",-1)),a[7]||(a[7]=e.createElementVNode("p",null,"Thank you for your payment.",-1)),e.createElementVNode("button",{class:"reevit-done-btn",onClick:S},"Done")])):T.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:3},[v.value==="ready"||v.value==="method_selected"||v.value==="processing"?(e.openBlock(),e.createBlock(j,{key:0,methods:n.paymentMethods||["card","mobile_money"],selected:w.value,amount:n.amount,currency:n.currency,onSelect:B},null,8,["methods","selected","amount","currency"])):e.createCommentVNode("",!0),(v.value==="method_selected"||v.value==="processing")&&w.value==="mobile_money"?(e.openBlock(),e.createElementBlock("div",Ne,[e.createVNode(A,{"initial-phone":n.phone,loading:v.value==="processing",onSubmit:P},null,8,["initial-phone","loading"])])):e.createCommentVNode("",!0),(v.value==="method_selected"||v.value==="processing")&&w.value==="card"?(e.openBlock(),e.createElementBlock("div",Ie,[a[8]||(a[8]=e.createElementVNode("p",{class:"reevit-info-text"},"You will be redirected to our secure payment partner to complete your card payment.",-1)),e.createElementVNode("button",{class:"reevit-submit-btn",onClick:P,disabled:v.value==="processing"},[v.value==="processing"?(e.openBlock(),e.createElementBlock("span",Re)):(e.openBlock(),e.createElementBlock("span",Ve,"Proceed to Card Payment"))],8,Me)])):e.createCommentVNode("",!0)],64)):e.createCommentVNode("",!0)]),a[10]||(a[10]=e.createElementVNode("div",{class:"reevit-modal-footer"},[e.createElementVNode("div",{class:"reevit-trust-badges"},[e.createElementVNode("span",null,"PCI DSS Compliant"),e.createElementVNode("span",null,"•"),e.createElementVNode("span",null,"SSL Secure")])],-1))],2)])):e.createCommentVNode("",!0)]))],4))}});Object.defineProperty(exports,"ReevitAPIClient",{enumerable:!0,get:()=>d.ReevitAPIClient});Object.defineProperty(exports,"cn",{enumerable:!0,get:()=>d.cn});Object.defineProperty(exports,"createReevitClient",{enumerable:!0,get:()=>d.createReevitClient});Object.defineProperty(exports,"detectCountryFromCurrency",{enumerable:!0,get:()=>d.detectCountryFromCurrency});Object.defineProperty(exports,"detectNetwork",{enumerable:!0,get:()=>d.detectNetwork});Object.defineProperty(exports,"formatAmount",{enumerable:!0,get:()=>d.formatAmount});Object.defineProperty(exports,"formatPhone",{enumerable:!0,get:()=>d.formatPhone});Object.defineProperty(exports,"validatePhone",{enumerable:!0,get:()=>d.validatePhone});exports.MobileMoneyForm=A;exports.PaymentMethodSelector=j;exports.ReevitCheckout=Be;exports.confirmStripePayment=fe;exports.createStripeInstance=G;exports.initiateMPesaSTKPush=be;exports.loadFlutterwaveScript=z;exports.loadHubtelScript=L;exports.loadMonnifyScript=x;exports.loadPaystackScript=K;exports.loadStripeScript=U;exports.openFlutterwaveModal=Y;exports.openHubtelPopup=q;exports.openMonnifyModal=ke;exports.openPaystackPopup=H;exports.useReevit=F;
package/dist/index.mjs CHANGED
@@ -1,53 +1,65 @@
1
- import { ref as R, watch as D, computed as h, readonly as k, defineComponent as V, createElementBlock as m, openBlock as l, createElementVNode as n, toDisplayString as C, unref as T, Fragment as z, renderList as W, normalizeClass as A, createCommentVNode as P, withModifiers as X, withDirectives as oe, vModelText as ae, createTextVNode as Z, normalizeStyle as ee, onUnmounted as re, renderSlot as Y, createBlock as G, Teleport as se, createVNode as ie } from "vue";
1
+ import { ref as N, watch as g, computed as h, readonly as S, defineComponent as z, createElementBlock as m, openBlock as d, createElementVNode as o, toDisplayString as I, unref as O, Fragment as H, renderList as W, normalizeClass as A, createCommentVNode as C, withModifiers as X, withDirectives as ae, vModelText as oe, createTextVNode as Z, normalizeStyle as ee, onUnmounted as re, renderSlot as Y, createBlock as G, Teleport as se, createVNode as ie } from "vue";
2
2
  import { createInitialState as le, ReevitAPIClient as ce, generateReference as ue, detectCountryFromCurrency as de, reevitReducer as me, formatAmount as pe, cn as te, detectNetwork as ye, validatePhone as J, createThemeVariables as ve } from "@reevit/core";
3
- import { ReevitAPIClient as yt, cn as vt, createReevitClient as ht, detectCountryFromCurrency as bt, detectNetwork as ft, formatAmount as kt, formatPhone as wt, validatePhone as St } from "@reevit/core";
3
+ import { ReevitAPIClient as yt, cn as vt, createReevitClient as ht, detectCountryFromCurrency as ft, detectNetwork as bt, formatAmount as kt, formatPhone as wt, validatePhone as St } from "@reevit/core";
4
4
  function he(e) {
5
- const r = e.toLowerCase();
6
- return r.includes("paystack") ? "paystack" : r.includes("hubtel") ? "hubtel" : r.includes("flutterwave") ? "flutterwave" : "paystack";
5
+ const s = e.toLowerCase();
6
+ return s.includes("paystack") ? "paystack" : s.includes("hubtel") ? "hubtel" : s.includes("flutterwave") ? "flutterwave" : "paystack";
7
7
  }
8
- function be(e, r) {
8
+ function fe(e, s) {
9
9
  return {
10
10
  id: e.id,
11
11
  clientSecret: e.client_secret,
12
+ pspPublicKey: e.psp_public_key,
12
13
  amount: e.amount,
13
14
  currency: e.currency,
14
15
  status: e.status,
15
16
  recommendedPsp: he(e.provider),
16
- availableMethods: r.paymentMethods || ["card", "mobile_money"],
17
+ availableMethods: s.paymentMethods || ["card", "mobile_money"],
18
+ reference: e.reference || s.reference,
17
19
  connectionId: e.connection_id,
18
20
  provider: e.provider,
19
21
  feeAmount: e.fee_amount,
20
22
  feeCurrency: e.fee_currency,
21
23
  netAmount: e.net_amount,
22
- metadata: r.metadata
24
+ metadata: s.metadata
23
25
  };
24
26
  }
25
- function fe(e) {
26
- const { config: r, onSuccess: t, onError: i, onClose: y, onStateChange: c, apiBaseUrl: u } = e, o = R(le()), w = new ce({
27
- publicKey: r.publicKey,
27
+ function be(e) {
28
+ const { config: s, onSuccess: t, onError: i, onClose: y, onStateChange: c, apiBaseUrl: u } = e, n = N(le());
29
+ if (s.initialPaymentIntent) {
30
+ const r = s.initialPaymentIntent;
31
+ n.value = {
32
+ ...n.value,
33
+ status: "ready",
34
+ paymentIntent: r,
35
+ selectedMethod: r.availableMethods?.length === 1 ? r.availableMethods[0] : null
36
+ };
37
+ }
38
+ const w = new ce({
39
+ publicKey: s.publicKey,
28
40
  baseUrl: u
29
- }), p = (s) => {
30
- o.value = me(o.value, s);
41
+ }), p = (r) => {
42
+ n.value = me(n.value, r);
31
43
  };
32
- D(
33
- () => o.value.status,
34
- (s) => {
35
- c?.(s);
44
+ g(
45
+ () => n.value.status,
46
+ (r) => {
47
+ c?.(r);
36
48
  }
37
49
  );
38
- const v = async (s) => {
50
+ const v = async (r) => {
39
51
  p({ type: "INIT_START" });
40
52
  try {
41
- const a = r.reference || ue(), d = de(r.currency), O = s || r.paymentMethods?.[0] || "card", { data: H, error: x } = await w.createPaymentIntent(
42
- { ...r, reference: a },
43
- O,
44
- d
53
+ const a = s.reference || ue(), l = de(s.currency), $ = r || s.paymentMethods?.[0] || "card", { data: k, error: V } = await w.createPaymentIntent(
54
+ { ...s, reference: a },
55
+ $,
56
+ l
45
57
  );
46
- if (x) {
47
- p({ type: "INIT_ERROR", payload: x }), i?.(x);
58
+ if (V) {
59
+ p({ type: "INIT_ERROR", payload: V }), i?.(V);
48
60
  return;
49
61
  }
50
- if (!H) {
62
+ if (!k) {
51
63
  const q = {
52
64
  code: "INIT_FAILED",
53
65
  message: "No data received from API",
@@ -56,94 +68,108 @@ function fe(e) {
56
68
  p({ type: "INIT_ERROR", payload: q }), i?.(q);
57
69
  return;
58
70
  }
59
- const ne = be(H, { ...r, reference: a });
71
+ const ne = fe(k, { ...s, reference: a });
60
72
  p({ type: "INIT_SUCCESS", payload: ne });
61
73
  } catch (a) {
62
- const d = {
74
+ const l = {
63
75
  code: "INIT_FAILED",
64
76
  message: a instanceof Error ? a.message : "Failed to initialize checkout",
65
77
  recoverable: !0,
66
78
  originalError: a
67
79
  };
68
- p({ type: "INIT_ERROR", payload: d }), i?.(d);
80
+ p({ type: "INIT_ERROR", payload: l }), i?.(l);
69
81
  }
70
- }, f = (s) => {
71
- p({ type: "SELECT_METHOD", payload: s });
72
- }, S = async (s) => {
73
- if (!(!o.value.paymentIntent || !o.value.selectedMethod)) {
82
+ }, b = (r) => {
83
+ p({ type: "SELECT_METHOD", payload: r });
84
+ }, _ = async (r) => {
85
+ if (!(!n.value.paymentIntent || !n.value.selectedMethod)) {
74
86
  p({ type: "PROCESS_START" });
75
87
  try {
76
- const { data: a, error: d } = await w.confirmPayment(o.value.paymentIntent.id);
77
- if (d) {
78
- p({ type: "PROCESS_ERROR", payload: d }), i?.(d);
79
- return;
88
+ let a;
89
+ if (n.value.paymentIntent.clientSecret) {
90
+ const { data: $, error: k } = await w.confirmPaymentIntent(
91
+ n.value.paymentIntent.id,
92
+ n.value.paymentIntent.clientSecret
93
+ );
94
+ if (k) {
95
+ p({ type: "PROCESS_ERROR", payload: k }), i?.(k);
96
+ return;
97
+ }
98
+ a = $;
99
+ } else {
100
+ const { data: $, error: k } = await w.confirmPayment(n.value.paymentIntent.id);
101
+ if (k) {
102
+ p({ type: "PROCESS_ERROR", payload: k }), i?.(k);
103
+ return;
104
+ }
105
+ a = $;
80
106
  }
81
- const O = {
82
- paymentId: o.value.paymentIntent.id,
83
- reference: s.reference || o.value.paymentIntent.metadata?.reference || "",
84
- amount: o.value.paymentIntent.amount,
85
- currency: o.value.paymentIntent.currency,
86
- paymentMethod: o.value.selectedMethod,
87
- psp: o.value.paymentIntent.recommendedPsp,
88
- pspReference: s.pspReference || a?.provider_ref_id || "",
107
+ const l = {
108
+ paymentId: n.value.paymentIntent.id,
109
+ reference: r.reference || n.value.paymentIntent.reference || n.value.paymentIntent.metadata?.reference || "",
110
+ amount: n.value.paymentIntent.amount,
111
+ currency: n.value.paymentIntent.currency,
112
+ paymentMethod: n.value.selectedMethod,
113
+ psp: n.value.paymentIntent.recommendedPsp,
114
+ pspReference: r.pspReference || a?.provider_ref_id || "",
89
115
  status: "success",
90
- metadata: s
116
+ metadata: r
91
117
  };
92
- p({ type: "PROCESS_SUCCESS", payload: O }), t?.(O);
118
+ p({ type: "PROCESS_SUCCESS", payload: l }), t?.(l);
93
119
  } catch (a) {
94
- const d = {
120
+ const l = {
95
121
  code: "PAYMENT_FAILED",
96
122
  message: a instanceof Error ? a.message : "Payment failed",
97
123
  recoverable: !0,
98
124
  originalError: a
99
125
  };
100
- p({ type: "PROCESS_ERROR", payload: d }), i?.(d);
126
+ p({ type: "PROCESS_ERROR", payload: l }), i?.(l);
101
127
  }
102
128
  }
103
- }, K = async (s) => {
104
- await S(s);
105
- }, L = (s) => {
106
- p({ type: "PROCESS_ERROR", payload: s }), i?.(s);
107
- }, _ = () => {
129
+ }, L = async (r) => {
130
+ await _(r);
131
+ }, U = (r) => {
132
+ p({ type: "PROCESS_ERROR", payload: r }), i?.(r);
133
+ }, P = () => {
108
134
  p({ type: "RESET" });
109
- }, N = async () => {
110
- if (o.value.paymentIntent && o.value.status !== "success")
135
+ }, D = async () => {
136
+ if (n.value.paymentIntent && n.value.status !== "success")
111
137
  try {
112
- await w.cancelPaymentIntent(o.value.paymentIntent.id);
138
+ await w.cancelPaymentIntent(n.value.paymentIntent.id);
113
139
  } catch {
114
140
  }
115
141
  p({ type: "CLOSE" }), y?.();
116
- }, E = h(() => o.value.status), U = h(() => o.value.paymentIntent), g = h(() => o.value.selectedMethod), B = h(() => o.value.error), b = h(() => o.value.result), F = h(
117
- () => o.value.status === "loading" || o.value.status === "processing"
118
- ), I = h(
119
- () => o.value.status === "ready" || o.value.status === "method_selected" || o.value.status === "processing"
120
- ), M = h(() => o.value.status === "success"), j = h(() => o.value.error?.recoverable ?? !1);
142
+ }, E = h(() => n.value.status), B = h(() => n.value.paymentIntent), R = h(() => n.value.selectedMethod), j = h(() => n.value.error), f = h(() => n.value.result), K = h(
143
+ () => n.value.status === "loading" || n.value.status === "processing"
144
+ ), M = h(
145
+ () => n.value.status === "ready" || n.value.status === "method_selected" || n.value.status === "processing"
146
+ ), T = h(() => n.value.status === "success"), x = h(() => n.value.error?.recoverable ?? !1);
121
147
  return {
122
148
  // State (readonly refs)
123
- status: k(E),
124
- paymentIntent: k(U),
125
- selectedMethod: k(g),
126
- error: k(B),
127
- result: k(b),
149
+ status: S(E),
150
+ paymentIntent: S(B),
151
+ selectedMethod: S(R),
152
+ error: S(j),
153
+ result: S(f),
128
154
  // Actions
129
155
  initialize: v,
130
- selectMethod: f,
131
- processPayment: S,
132
- handlePspSuccess: K,
133
- handlePspError: L,
134
- reset: _,
135
- close: N,
156
+ selectMethod: b,
157
+ processPayment: _,
158
+ handlePspSuccess: L,
159
+ handlePspError: U,
160
+ reset: P,
161
+ close: D,
136
162
  // Computed
137
- isLoading: k(F),
138
- isReady: k(I),
139
- isComplete: k(M),
140
- canRetry: k(j)
163
+ isLoading: S(K),
164
+ isReady: S(M),
165
+ isComplete: S(T),
166
+ canRetry: S(x)
141
167
  };
142
168
  }
143
- const ke = { class: "reevit-method-selector" }, we = { class: "reevit-amount-display" }, Se = { class: "reevit-methods-grid" }, _e = ["onClick"], Pe = { class: "reevit-method-icon" }, Ce = { class: "reevit-method-info" }, Ee = { class: "reevit-method-name" }, Ie = { class: "reevit-method-description" }, Me = { class: "reevit-method-radio" }, Re = {
169
+ const ke = { class: "reevit-method-selector" }, we = { class: "reevit-amount-display" }, Se = { class: "reevit-methods-grid" }, Pe = ["onClick"], _e = { class: "reevit-method-icon" }, Ce = { class: "reevit-method-info" }, Ie = { class: "reevit-method-name" }, Ee = { class: "reevit-method-description" }, Re = { class: "reevit-method-radio" }, Me = {
144
170
  key: 0,
145
171
  class: "reevit-radio-inner"
146
- }, Te = /* @__PURE__ */ V({
172
+ }, Te = /* @__PURE__ */ z({
147
173
  __name: "PaymentMethodSelector",
148
174
  props: {
149
175
  methods: {},
@@ -152,8 +178,8 @@ const ke = { class: "reevit-method-selector" }, we = { class: "reevit-amount-dis
152
178
  currency: {}
153
179
  },
154
180
  emits: ["select"],
155
- setup(e, { emit: r }) {
156
- const t = e, i = r, y = h(() => [
181
+ setup(e, { emit: s }) {
182
+ const t = e, i = s, y = h(() => [
157
183
  {
158
184
  id: "card",
159
185
  name: "Card",
@@ -173,48 +199,48 @@ const ke = { class: "reevit-method-selector" }, we = { class: "reevit-amount-dis
173
199
  icon: "🏦"
174
200
  }
175
201
  ].filter((c) => t.methods.includes(c.id)));
176
- return (c, u) => (l(), m("div", ke, [
177
- u[0] || (u[0] = n("h3", { class: "reevit-section-title" }, "Select Payment Method", -1)),
178
- n("p", we, " Pay " + C(T(pe)(e.amount, e.currency)), 1),
179
- n("div", Se, [
180
- (l(!0), m(z, null, W(y.value, (o) => (l(), m("button", {
181
- key: o.id,
202
+ return (c, u) => (d(), m("div", ke, [
203
+ u[0] || (u[0] = o("h3", { class: "reevit-section-title" }, "Select Payment Method", -1)),
204
+ o("p", we, " Pay " + I(O(pe)(e.amount, e.currency)), 1),
205
+ o("div", Se, [
206
+ (d(!0), m(H, null, W(y.value, (n) => (d(), m("button", {
207
+ key: n.id,
182
208
  type: "button",
183
- class: A(T(te)("reevit-method-card", e.selected === o.id && "reevit-method-card--selected")),
184
- onClick: (w) => i("select", o.id)
209
+ class: A(O(te)("reevit-method-card", e.selected === n.id && "reevit-method-card--selected")),
210
+ onClick: (w) => i("select", n.id)
185
211
  }, [
186
- n("span", Pe, C(o.icon), 1),
187
- n("div", Ce, [
188
- n("span", Ee, C(o.name), 1),
189
- n("span", Ie, C(o.description), 1)
212
+ o("span", _e, I(n.icon), 1),
213
+ o("div", Ce, [
214
+ o("span", Ie, I(n.name), 1),
215
+ o("span", Ee, I(n.description), 1)
190
216
  ]),
191
- n("div", Me, [
192
- e.selected === o.id ? (l(), m("div", Re)) : P("", !0)
217
+ o("div", Re, [
218
+ e.selected === n.id ? (d(), m("div", Me)) : C("", !0)
193
219
  ])
194
- ], 10, _e))), 128))
220
+ ], 10, Pe))), 128))
195
221
  ])
196
222
  ]));
197
223
  }
198
- }), $e = { class: "reevit-form-group" }, Ne = ["disabled"], ge = { class: "reevit-network-selector" }, Fe = { class: "reevit-networks-grid" }, Oe = ["onClick", "disabled"], De = {
224
+ }), $e = { class: "reevit-form-group" }, Ne = ["disabled"], ge = { class: "reevit-network-selector" }, Oe = { class: "reevit-networks-grid" }, Fe = ["onClick", "disabled"], De = {
199
225
  key: 0,
200
226
  class: "reevit-error-message"
201
- }, Ae = ["disabled"], Ke = {
227
+ }, Ke = ["disabled"], Ae = {
202
228
  key: 0,
203
229
  class: "reevit-spinner"
204
- }, Le = { key: 1 }, Ue = /* @__PURE__ */ V({
230
+ }, Le = { key: 1 }, Ue = /* @__PURE__ */ z({
205
231
  __name: "MobileMoneyForm",
206
232
  props: {
207
233
  initialPhone: {},
208
234
  loading: { type: Boolean }
209
235
  },
210
236
  emits: ["submit"],
211
- setup(e, { emit: r }) {
212
- const t = e, i = r, y = R(t.initialPhone || ""), c = R(null), u = R(null);
213
- D(y, (p) => {
237
+ setup(e, { emit: s }) {
238
+ const t = e, i = s, y = N(t.initialPhone || ""), c = N(null), u = N(null);
239
+ g(y, (p) => {
214
240
  const v = ye(p);
215
241
  v && (c.value = v), u.value && (u.value = null);
216
242
  });
217
- const o = () => {
243
+ const n = () => {
218
244
  if (!J(y.value)) {
219
245
  u.value = "Please enter a valid phone number";
220
246
  return;
@@ -232,84 +258,84 @@ const ke = { class: "reevit-method-selector" }, we = { class: "reevit-amount-dis
232
258
  { id: "vodafone", name: "Vodafone", color: "#E60000" },
233
259
  { id: "airteltigo", name: "AirtelTigo", color: "#005596" }
234
260
  ];
235
- return (p, v) => (l(), m("form", {
261
+ return (p, v) => (d(), m("form", {
236
262
  class: "reevit-momo-form",
237
- onSubmit: X(o, ["prevent"])
263
+ onSubmit: X(n, ["prevent"])
238
264
  }, [
239
- n("div", $e, [
240
- v[1] || (v[1] = n("label", {
265
+ o("div", $e, [
266
+ v[1] || (v[1] = o("label", {
241
267
  class: "reevit-label",
242
268
  for: "reevit-phone"
243
269
  }, "Phone Number", -1)),
244
- oe(n("input", {
270
+ ae(o("input", {
245
271
  id: "reevit-phone",
246
- "onUpdate:modelValue": v[0] || (v[0] = (f) => y.value = f),
272
+ "onUpdate:modelValue": v[0] || (v[0] = (b) => y.value = b),
247
273
  type: "tel",
248
- class: A(["reevit-input", { "reevit-input--error": u.value && !T(J)(y.value) }]),
274
+ class: A(["reevit-input", { "reevit-input--error": u.value && !O(J)(y.value) }]),
249
275
  placeholder: "e.g. 024 123 4567",
250
276
  disabled: e.loading,
251
277
  autocomplete: "tel"
252
278
  }, null, 10, Ne), [
253
- [ae, y.value]
279
+ [oe, y.value]
254
280
  ])
255
281
  ]),
256
- n("div", ge, [
257
- v[2] || (v[2] = n("label", { class: "reevit-label" }, "Select Network", -1)),
258
- n("div", Fe, [
259
- (l(), m(z, null, W(w, (f) => n("button", {
260
- key: f.id,
282
+ o("div", ge, [
283
+ v[2] || (v[2] = o("label", { class: "reevit-label" }, "Select Network", -1)),
284
+ o("div", Oe, [
285
+ (d(), m(H, null, W(w, (b) => o("button", {
286
+ key: b.id,
261
287
  type: "button",
262
- class: A(T(te)("reevit-network-btn", c.value === f.id && "reevit-network-btn--selected")),
263
- onClick: (S) => c.value = f.id,
288
+ class: A(O(te)("reevit-network-btn", c.value === b.id && "reevit-network-btn--selected")),
289
+ onClick: (_) => c.value = b.id,
264
290
  disabled: e.loading
265
291
  }, [
266
- n("div", {
292
+ o("div", {
267
293
  class: "reevit-network-dot",
268
- style: ee({ backgroundColor: f.color })
294
+ style: ee({ backgroundColor: b.color })
269
295
  }, null, 4),
270
- Z(" " + C(f.name), 1)
271
- ], 10, Oe)), 64))
296
+ Z(" " + I(b.name), 1)
297
+ ], 10, Fe)), 64))
272
298
  ])
273
299
  ]),
274
- u.value ? (l(), m("p", De, C(u.value), 1)) : P("", !0),
275
- n("button", {
300
+ u.value ? (d(), m("p", De, I(u.value), 1)) : C("", !0),
301
+ o("button", {
276
302
  type: "submit",
277
303
  class: "reevit-submit-btn",
278
304
  disabled: e.loading || !y.value
279
305
  }, [
280
- e.loading ? (l(), m("span", Ke)) : (l(), m("span", Le, "Continue"))
281
- ], 8, Ae),
282
- v[3] || (v[3] = n("p", { class: "reevit-secure-text" }, " 🔒 Secure mobile money payment via Reevit ", -1))
306
+ e.loading ? (d(), m("span", Ae)) : (d(), m("span", Le, "Continue"))
307
+ ], 8, Ke),
308
+ v[3] || (v[3] = o("p", { class: "reevit-secure-text" }, " 🔒 Secure mobile money payment via Reevit ", -1))
283
309
  ], 32));
284
310
  }
285
311
  }), Q = /* @__PURE__ */ new Map();
286
- function $(e, r) {
287
- const t = Q.get(r);
312
+ function F(e, s) {
313
+ const t = Q.get(s);
288
314
  if (t) return t;
289
315
  const i = new Promise((y, c) => {
290
- if (document.getElementById(r)) {
316
+ if (document.getElementById(s)) {
291
317
  y();
292
318
  return;
293
319
  }
294
320
  const u = document.createElement("script");
295
- u.id = r, u.src = e, u.async = !0, u.onload = () => y(), u.onerror = () => c(new Error(`Failed to load ${r} script`)), document.head.appendChild(u);
321
+ u.id = s, u.src = e, u.async = !0, u.onload = () => y(), u.onerror = () => c(new Error(`Failed to load ${s} script`)), document.head.appendChild(u);
296
322
  });
297
- return Q.set(r, i), i;
323
+ return Q.set(s, i), i;
298
324
  }
299
325
  function Be() {
300
- return $("https://js.paystack.co/v1/inline.js", "paystack-script");
326
+ return F("https://js.paystack.co/v1/inline.js", "paystack-script");
301
327
  }
302
328
  function je() {
303
- return $("https://checkout.hubtel.com/js/hubtel-checkout.js", "hubtel-script");
329
+ return F("https://checkout.hubtel.com/js/hubtel-checkout.js", "hubtel-script");
304
330
  }
305
331
  function xe() {
306
- return $("https://checkout.flutterwave.com/v3.js", "flutterwave-script");
332
+ return F("https://checkout.flutterwave.com/v3.js", "flutterwave-script");
307
333
  }
308
334
  function Ve() {
309
- return $("https://js.stripe.com/v3/", "stripe-script");
335
+ return F("https://js.stripe.com/v3/", "stripe-script");
310
336
  }
311
337
  function ze() {
312
- return $("https://sdk.monnify.com/plugin/monnify.js", "monnify-script");
338
+ return F("https://sdk.monnify.com/plugin/monnify.js", "monnify-script");
313
339
  }
314
340
  async function He(e) {
315
341
  if (await Be(), !window.PaystackPop)
@@ -385,20 +411,20 @@ async function ct(e) {
385
411
  paymentDescription: e.paymentDescription || "Payment",
386
412
  isTestMode: e.isTestMode ?? !1,
387
413
  metadata: e.metadata,
388
- onComplete: (r) => {
389
- r.status === "SUCCESS" ? e.onSuccess({
390
- transactionReference: r.transactionReference,
391
- paymentReference: r.paymentReference,
392
- ...r
393
- }) : e.onError?.({ message: r.message || "Payment failed" });
414
+ onComplete: (s) => {
415
+ s.status === "SUCCESS" ? e.onSuccess({
416
+ transactionReference: s.transactionReference,
417
+ paymentReference: s.paymentReference,
418
+ ...s
419
+ }) : e.onError?.({ message: s.message || "Payment failed" });
394
420
  },
395
421
  onClose: e.onClose
396
422
  });
397
423
  }
398
- async function ut(e, r) {
424
+ async function ut(e, s) {
399
425
  e.onInitiated();
400
426
  try {
401
- const t = await fetch(r, {
427
+ const t = await fetch(s, {
402
428
  method: "POST",
403
429
  headers: { "Content-Type": "application/json" },
404
430
  body: JSON.stringify({
@@ -441,10 +467,10 @@ const Je = ["disabled"], Qe = {
441
467
  }, nt = {
442
468
  key: 2,
443
469
  class: "reevit-card-info"
444
- }, ot = ["disabled"], at = {
470
+ }, at = ["disabled"], ot = {
445
471
  key: 0,
446
472
  class: "reevit-spinner"
447
- }, rt = { key: 1 }, dt = /* @__PURE__ */ V({
473
+ }, rt = { key: 1 }, dt = /* @__PURE__ */ z({
448
474
  __name: "ReevitCheckout",
449
475
  props: {
450
476
  publicKey: {},
@@ -457,23 +483,24 @@ const Je = ["disabled"], Qe = {
457
483
  paymentMethods: {},
458
484
  theme: {},
459
485
  isOpen: { type: Boolean },
460
- apiBaseUrl: {}
486
+ apiBaseUrl: {},
487
+ initialPaymentIntent: {}
461
488
  },
462
489
  emits: ["success", "error", "close"],
463
- setup(e, { emit: r }) {
464
- const t = e, i = r, {
490
+ setup(e, { emit: s }) {
491
+ const t = e, i = s, {
465
492
  status: y,
466
493
  paymentIntent: c,
467
494
  selectedMethod: u,
468
- error: o,
495
+ error: n,
469
496
  isLoading: w,
470
497
  isReady: p,
471
498
  initialize: v,
472
- selectMethod: f,
473
- handlePspSuccess: S,
474
- handlePspError: K,
475
- close: L
476
- } = fe({
499
+ selectMethod: b,
500
+ handlePspSuccess: _,
501
+ handlePspError: L,
502
+ close: U
503
+ } = be({
477
504
  config: {
478
505
  publicKey: t.publicKey,
479
506
  amount: t.amount,
@@ -482,23 +509,28 @@ const Je = ["disabled"], Qe = {
482
509
  phone: t.phone,
483
510
  reference: t.reference,
484
511
  metadata: t.metadata,
485
- paymentMethods: t.paymentMethods
512
+ paymentMethods: t.paymentMethods,
513
+ initialPaymentIntent: t.initialPaymentIntent
486
514
  },
487
515
  apiBaseUrl: t.apiBaseUrl,
488
- onSuccess: (s) => i("success", s),
489
- onError: (s) => i("error", s),
516
+ onSuccess: (r) => i("success", r),
517
+ onError: (r) => i("error", r),
490
518
  onClose: () => i("close")
491
- }), _ = R(t.isOpen ?? !1);
492
- D(() => t.isOpen, (s) => {
493
- s !== void 0 && (_.value = s);
519
+ }), P = N(t.isOpen ?? !1);
520
+ g(() => t.isOpen, (r) => {
521
+ r !== void 0 && (P.value = r);
522
+ });
523
+ const D = () => {
524
+ P.value = !0, !c.value && y.value === "idle" && v();
525
+ };
526
+ g([P, c, u], ([r, a, l]) => {
527
+ r && a && l && l === "card" && R(null);
494
528
  });
495
- const N = () => {
496
- _.value = !0, c.value || v();
497
- }, E = () => {
498
- _.value = !1, L();
499
- }, U = (s) => {
500
- f(s);
501
- }, g = async (s) => {
529
+ const E = () => {
530
+ P.value = !1, U();
531
+ }, B = (r) => {
532
+ b(r);
533
+ }, R = async (r) => {
502
534
  if (!c.value) return;
503
535
  const a = c.value.recommendedPsp;
504
536
  try {
@@ -508,16 +540,16 @@ const Je = ["disabled"], Qe = {
508
540
  amount: t.amount,
509
541
  currency: t.currency,
510
542
  ref: c.value.id,
511
- onSuccess: (d) => S(d),
543
+ onSuccess: (l) => _(l),
512
544
  onClose: () => {
513
545
  }
514
546
  }) : a === "hubtel" ? await qe({
515
547
  clientId: t.publicKey,
516
548
  purchaseDescription: `Payment for ${t.amount} ${t.currency}`,
517
549
  amount: t.amount,
518
- customerPhone: s?.phone || t.phone,
550
+ customerPhone: r?.phone || t.phone,
519
551
  customerEmail: t.email,
520
- onSuccess: (d) => S(d),
552
+ onSuccess: (l) => _(l),
521
553
  onClose: () => {
522
554
  }
523
555
  }) : a === "flutterwave" && await Ye({
@@ -527,122 +559,122 @@ const Je = ["disabled"], Qe = {
527
559
  currency: t.currency,
528
560
  customer: {
529
561
  email: t.email || "",
530
- phone_number: s?.phone || t.phone
562
+ phone_number: r?.phone || t.phone
531
563
  },
532
- callback: (d) => S(d),
564
+ callback: (l) => _(l),
533
565
  onclose: () => {
534
566
  }
535
567
  });
536
- } catch (d) {
537
- K({
568
+ } catch (l) {
569
+ L({
538
570
  code: "BRIDGE_ERROR",
539
- message: d instanceof Error ? d.message : "Failed to open payment gateway"
571
+ message: l instanceof Error ? l.message : "Failed to open payment gateway"
540
572
  });
541
573
  }
542
- }, B = h(() => ve(t.theme || {}));
543
- D(_, (s) => {
544
- s ? document.body.style.overflow = "hidden" : document.body.style.overflow = "";
574
+ }, j = h(() => ve(t.theme || {}));
575
+ g(P, (r) => {
576
+ r ? document.body.style.overflow = "hidden" : document.body.style.overflow = "";
545
577
  }), re(() => {
546
578
  document.body.style.overflow = "";
547
579
  });
548
- const b = h(() => y.value), F = h(() => o.value), I = h(() => u.value), M = h(() => w.value), j = h(() => p.value);
549
- return (s, a) => (l(), m("div", {
580
+ const f = h(() => y.value), K = h(() => n.value), M = h(() => u.value), T = h(() => w.value), x = h(() => p.value);
581
+ return (r, a) => (d(), m("div", {
550
582
  class: "reevit-sdk-container",
551
- style: ee(B.value)
583
+ style: ee(j.value)
552
584
  }, [
553
- Y(s.$slots, "default", {
554
- open: N,
555
- isLoading: M.value
585
+ Y(r.$slots, "default", {
586
+ open: D,
587
+ isLoading: T.value
556
588
  }, () => [
557
- n("button", {
589
+ o("button", {
558
590
  type: "button",
559
591
  class: "reevit-pay-button",
560
- onClick: N,
561
- disabled: M.value
592
+ onClick: D,
593
+ disabled: T.value
562
594
  }, [
563
- M.value ? (l(), m("span", Qe)) : Y(s.$slots, "button-text", { key: 1 }, () => [
595
+ T.value ? (d(), m("span", Qe)) : Y(r.$slots, "button-text", { key: 1 }, () => [
564
596
  a[1] || (a[1] = Z("Pay Now", -1))
565
597
  ])
566
598
  ], 8, Je)
567
599
  ]),
568
- (l(), G(se, { to: "body" }, [
569
- _.value ? (l(), m("div", {
600
+ (d(), G(se, { to: "body" }, [
601
+ P.value ? (d(), m("div", {
570
602
  key: 0,
571
603
  class: "reevit-modal-overlay",
572
604
  onClick: X(E, ["self"])
573
605
  }, [
574
- n("div", {
606
+ o("div", {
575
607
  class: A(["reevit-modal-content", { "reevit-modal--dark": t.theme?.darkMode }])
576
608
  }, [
577
- n("button", {
609
+ o("button", {
578
610
  class: "reevit-modal-close",
579
611
  onClick: E,
580
612
  "aria-label": "Close"
581
613
  }, " × "),
582
- a[9] || (a[9] = n("div", { class: "reevit-modal-header" }, [
583
- n("img", {
614
+ a[9] || (a[9] = o("div", { class: "reevit-modal-header" }, [
615
+ o("img", {
584
616
  src: "https://i.imgur.com/bzUR5Lm.png",
585
617
  alt: "Reevit",
586
618
  class: "reevit-modal__logo"
587
619
  })
588
620
  ], -1)),
589
- n("div", We, [
590
- b.value === "loading" ? (l(), m("div", Xe, [...a[2] || (a[2] = [
591
- n("div", { class: "reevit-spinner reevit-spinner--large" }, null, -1),
592
- n("p", null, "Initializing payment...", -1)
593
- ])])) : b.value === "failed" && F.value ? (l(), m("div", Ze, [
594
- a[3] || (a[3] = n("div", { class: "reevit-error-icon" }, "⚠️", -1)),
595
- a[4] || (a[4] = n("h3", null, "Payment Failed", -1)),
596
- n("p", null, C(F.value.message), 1),
597
- n("button", {
621
+ o("div", We, [
622
+ f.value === "loading" ? (d(), m("div", Xe, [...a[2] || (a[2] = [
623
+ o("div", { class: "reevit-spinner reevit-spinner--large" }, null, -1),
624
+ o("p", null, "Initializing payment...", -1)
625
+ ])])) : f.value === "failed" && K.value ? (d(), m("div", Ze, [
626
+ a[3] || (a[3] = o("div", { class: "reevit-error-icon" }, "⚠️", -1)),
627
+ a[4] || (a[4] = o("h3", null, "Payment Failed", -1)),
628
+ o("p", null, I(K.value.message), 1),
629
+ o("button", {
598
630
  class: "reevit-retry-btn",
599
- onClick: a[0] || (a[0] = (d) => T(v)())
631
+ onClick: a[0] || (a[0] = (l) => O(v)())
600
632
  }, "Retry")
601
- ])) : b.value === "success" ? (l(), m("div", et, [
602
- a[5] || (a[5] = n("div", { class: "reevit-success-icon" }, "✅", -1)),
603
- a[6] || (a[6] = n("h3", null, "Payment Successful", -1)),
604
- a[7] || (a[7] = n("p", null, "Thank you for your payment.", -1)),
605
- n("button", {
633
+ ])) : f.value === "success" ? (d(), m("div", et, [
634
+ a[5] || (a[5] = o("div", { class: "reevit-success-icon" }, "✅", -1)),
635
+ a[6] || (a[6] = o("h3", null, "Payment Successful", -1)),
636
+ a[7] || (a[7] = o("p", null, "Thank you for your payment.", -1)),
637
+ o("button", {
606
638
  class: "reevit-done-btn",
607
639
  onClick: E
608
640
  }, "Done")
609
- ])) : j.value ? (l(), m(z, { key: 3 }, [
610
- b.value === "ready" || b.value === "method_selected" || b.value === "processing" ? (l(), G(Te, {
641
+ ])) : x.value ? (d(), m(H, { key: 3 }, [
642
+ f.value === "ready" || f.value === "method_selected" || f.value === "processing" ? (d(), G(Te, {
611
643
  key: 0,
612
644
  methods: t.paymentMethods || ["card", "mobile_money"],
613
- selected: I.value,
645
+ selected: M.value,
614
646
  amount: t.amount,
615
647
  currency: t.currency,
616
- onSelect: U
617
- }, null, 8, ["methods", "selected", "amount", "currency"])) : P("", !0),
618
- (b.value === "method_selected" || b.value === "processing") && I.value === "mobile_money" ? (l(), m("div", tt, [
648
+ onSelect: B
649
+ }, null, 8, ["methods", "selected", "amount", "currency"])) : C("", !0),
650
+ (f.value === "method_selected" || f.value === "processing") && M.value === "mobile_money" ? (d(), m("div", tt, [
619
651
  ie(Ue, {
620
652
  "initial-phone": t.phone,
621
- loading: b.value === "processing",
622
- onSubmit: g
653
+ loading: f.value === "processing",
654
+ onSubmit: R
623
655
  }, null, 8, ["initial-phone", "loading"])
624
- ])) : P("", !0),
625
- (b.value === "method_selected" || b.value === "processing") && I.value === "card" ? (l(), m("div", nt, [
626
- a[8] || (a[8] = n("p", { class: "reevit-info-text" }, "You will be redirected to our secure payment partner to complete your card payment.", -1)),
627
- n("button", {
656
+ ])) : C("", !0),
657
+ (f.value === "method_selected" || f.value === "processing") && M.value === "card" ? (d(), m("div", nt, [
658
+ a[8] || (a[8] = o("p", { class: "reevit-info-text" }, "You will be redirected to our secure payment partner to complete your card payment.", -1)),
659
+ o("button", {
628
660
  class: "reevit-submit-btn",
629
- onClick: g,
630
- disabled: b.value === "processing"
661
+ onClick: R,
662
+ disabled: f.value === "processing"
631
663
  }, [
632
- b.value === "processing" ? (l(), m("span", at)) : (l(), m("span", rt, "Proceed to Card Payment"))
633
- ], 8, ot)
634
- ])) : P("", !0)
635
- ], 64)) : P("", !0)
664
+ f.value === "processing" ? (d(), m("span", ot)) : (d(), m("span", rt, "Proceed to Card Payment"))
665
+ ], 8, at)
666
+ ])) : C("", !0)
667
+ ], 64)) : C("", !0)
636
668
  ]),
637
- a[10] || (a[10] = n("div", { class: "reevit-modal-footer" }, [
638
- n("div", { class: "reevit-trust-badges" }, [
639
- n("span", null, "PCI DSS Compliant"),
640
- n("span", null, "•"),
641
- n("span", null, "SSL Secure")
669
+ a[10] || (a[10] = o("div", { class: "reevit-modal-footer" }, [
670
+ o("div", { class: "reevit-trust-badges" }, [
671
+ o("span", null, "PCI DSS Compliant"),
672
+ o("span", null, "•"),
673
+ o("span", null, "SSL Secure")
642
674
  ])
643
675
  ], -1))
644
676
  ], 2)
645
- ])) : P("", !0)
677
+ ])) : C("", !0)
646
678
  ]))
647
679
  ], 4));
648
680
  }
@@ -656,8 +688,8 @@ export {
656
688
  lt as confirmStripePayment,
657
689
  ht as createReevitClient,
658
690
  Ge as createStripeInstance,
659
- bt as detectCountryFromCurrency,
660
- ft as detectNetwork,
691
+ ft as detectCountryFromCurrency,
692
+ bt as detectNetwork,
661
693
  kt as formatAmount,
662
694
  wt as formatPhone,
663
695
  ut as initiateMPesaSTKPush,
@@ -670,6 +702,6 @@ export {
670
702
  qe as openHubtelPopup,
671
703
  ct as openMonnifyModal,
672
704
  He as openPaystackPopup,
673
- fe as useReevit,
705
+ be as useReevit,
674
706
  St as validatePhone
675
707
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reevit/vue",
3
- "version": "0.2.5",
3
+ "version": "0.3.2",
4
4
  "description": "Unified Payment Widget for Vue 3 Applications",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -44,7 +44,7 @@
44
44
  "vue": "^3.3.0"
45
45
  },
46
46
  "dependencies": {
47
- "@reevit/core": "^0.2.5"
47
+ "@reevit/core": "^0.3.2"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@types/node": "^20.0.0",