PageSourceSearch

https://unitedkenyaclub.com/assets/payment_.callback-DL9zitks.js

js unitedkenyaclub.com collected 2026-09-28 23:58:55 UTC 16,509 bytes, 1 lines download raw bytes

1import{h as le,r as d,j as t,m as K,S as de,a3 as me}from"./index-A6wiMamB.js";import{F as w}from"./file-text-CS9THXMm.js";import{C as Q}from"./calendar-days-t0vv-Cf_.js";import{C as G}from"./clock-o_T0qMZJ.js";import{M as ue}from"./mail-D0ApL9bu.js";import{P as pe}from"./pesapalPayment-pG2D_L1J.js";import{C as fe}from"./cancellationpolicy-D_snf9HF.js";import{E as he}from"./external-link-BveGtWKr.js";import"./loader-circle-vA7YbvLd.js";import"./minimize-2-BJZbPKVD.js";const ye=[["path",{d:"M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384",key:"9njp5v"}]],J=le("phone",ye),ge="https://ukc-backend.unitedkenyaclublibrary.workers.dev/api",r=(...e)=>e.find(n=>n!=null&&n!=="")??"",V=e=>{if(!e||typeof e!="string")return"";const n=new Date(e);return Number.isNaN(n.getTime())?e:n.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"})},xe=e=>{if(!e||typeof e!="object")return null;const n=e,o=n.data??n.reservation??n.result??n;return Array.isArray(o)?o[0]??null:o&&typeof o=="object"?o:null};async function be(e){const n=await fetch(`${ge}/reservation/${encodeURIComponent(e)}`,{headers:{"ngrok-skip-browser-warning":"true"}});if(!n.ok)throw new Error("Reservation not found.");return xe(await n.json())}function ve({reservationCode:e="",reservation:n=null,compact:o=!1}){const[h,p]=d.useState(n),[j,i]=d.useState(n?"success":e?"loading":"idle"),[c,g]=d.useState("");d.useEffect(()=>{if(n){p(n),i("success");return}if(!e){i("idle");return}let a=!1;return(async()=>{i("loading"),g("");try{const b=await be(e);if(a)return;b?(p(b),i("success")):(i("error"),g("We could not find that reservation."))}catch{a||(i("error"),g("Unable to retrieve this reservation. Please contact the club."))}})(),()=>{a=!0}},[n,e]);const s=d.useMemo(()=>{const a=h??{};return{code:String(r(a.reservation_id,a.id,e)),roomTitle:String(r(a.room_title,"Reservation")),roomQuantity:Math.max(Number(r(a.room_quantity,1))||1,1),packageName:String(r(a.package_name)),checkIn:V(r(a.check_in_date)),checkOut:V(r(a.check_out_date)),checkInTime:String(r(a.check_in_time)),checkOutTime:String(r(a.check_out_time)),guestName:[r(a.first_name),r(a.last_name)].filter(Boolean).join(" "),email:String(r(a.email)),phone:String(r(a.phone)),guests:[r(a.adults)!==""?`${r(a.adults)} ${Number(r(a.adults))===1?"adult":"adults"}`:"",r(a.children)!==""?`${r(a.children)} ${Number(r(a.children))===1?"child":"children"}`:""].filter(Boolean).join(", "),alternativeContact:[r(a.alternative_contact_name),r(a.alternative_contact_email),r(a.alternative_contact_phone)].filter(Boolean).join(" / "),confirmationStatus:String(r(a.confirmation_status,a.status,"pending")),paymentStatus:String(r(a.payment_status,"awaiting_payment")),paymentMethod:String(r(a.payment_method)),refundPending:!!r(a.refund_pending,!1),totalAmount:r(a.total_amount),currency:String(r(a.currency,"USD")),paymentUrl:String(r(a.payment_url)),historyStatus:String(r(a.history_status))}},[h,e]);return t.jsx("section",{className:o?"bg-transparent":"min-h-screen bg-cream px-6 py-24",children:t.jsxs("div",{className:"mx-auto max-w-3xl border border-border bg-card",children:[t.jsx("div",{className:"border-b border-border px-6 py-6 md:px-8",children:t.jsxs("div",{className:"flex items-start justify-between gap-5",children:[t.jsxs("div",{children:[t.jsx("p",{className:"text-xs uppercase tracking-[0.3em] text-gold",children:"United Kenya Club"}),t.jsx("h1",{className:"mt-2 font-serif text-3xl text-forest",children:"Reservation Details"})]}),t.jsx(K,{className:"mt-1 h-8 w-8 text-gold"})]})}),t.jsxs("div",{className:"px-6 py-6 md:px-8",children:[j==="loading"&&t.jsxs("div",{className:"flex items-center gap-3 text-sm text-muted-foreground",children:[t.jsx(de,{className:"h-4 w-4 animate-spin text-gold"}),"Retrieving reservation details..."]}),j==="error"&&t.jsx("p",{className:"border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive",children:c}),j==="idle"&&t.jsx("p",{className:"text-sm text-muted-foreground",children:"Provide a reservation code to retrieve the confirmed reservation receipt."}),j==="success"&&t.jsxs("div",{className:"space-y-6",children:[t.jsxs("div",{className:"border border-gold/40 bg-gold/10 px-5 py-4",children:[t.jsx("p",{className:"text-xs uppercase tracking-[0.24em] text-muted-foreground",children:"Reservation Code"}),t.jsx("p",{className:"mt-1 break-all font-serif text-2xl text-forest",children:s.code})]}),t.jsxs("div",{className:"grid gap-4 md:grid-cols-2",children:[t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Room",value:s.roomTitle}),s.roomQuantity>1&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Rooms",value:`${s.roomQuantity}`}),t.jsx(u,{icon:t.jsx(K,{size:18}),label:"Confirmation",value:s.confirmationStatus}),t.jsx(u,{icon:t.jsx(Q,{size:18}
1),label:"Check-in",value:[s.checkIn,s.checkInTime].filter(Boolean).join(" at ")||"Pending"}),t.jsx(u,{icon:t.jsx(Q,{size:18}),label:"Check-out",value:[s.checkOut,s.checkOutTime].filter(Boolean).join(" at ")||"Pending"}),s.historyStatus&&t.jsx(u,{icon:t.jsx(G,{size:18}),label:"Timeline",value:s.historyStatus}),s.packageName&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Package",value:s.packageName}),t.jsx(u,{icon:t.jsx(G,{size:18}),label:"Payment",value:s.refundPending?"Refund Pending":s.paymentStatus}),s.paymentMethod&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Payment Method",value:s.paymentMethod}),s.guestName&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Guest",value:s.guestName}),s.email&&t.jsx(u,{icon:t.jsx(ue,{size:18}),label:"Email",value:s.email}),s.phone&&t.jsx(u,{icon:t.jsx(J,{size:18}),label:"Phone",value:s.phone}),s.guests&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Guests",value:s.guests}),s.alternativeContact&&t.jsx(u,{icon:t.jsx(J,{size:18}),label:"Alternative Contact",value:s.alternativeContact}),s.totalAmount&&t.jsx(u,{icon:t.jsx(w,{size:18}),label:"Total",value:`${s.currency} ${s.totalAmount}`})]})]})]})]})})}function u({icon:e,label:n,value:o}){return t.jsxs("div",{className:"flex gap-3 border border-border bg-cream px-4 py-3",children:[t.jsx("div",{className:"mt-0.5 text-gold",children:e}),t.jsxs("div",{children:[t.jsx("p",{className:"text-xs uppercase tracking-[0.18em] text-muted-foreground",children:n}),t.jsx("p",{className:"mt-1 text-sm text-forest",children:o})]})]})}const P="https://ukc-backend.unitedkenyaclublibrary.workers.dev/api",A="ukc-pesapal-payment-update",z=e=>String(e.paymentStatus??e.payment_status_description??e.status??e.orderStatus??e.orderPaymentStatus??"").toLowerCase(),we=e=>{const n=z(e);return e.paid===!0||e.paymentConfirmed===!0||e.completed===!0||["completed","complete","paid","success","confirmed"].includes(n)},je=e=>["failed","cancelled","canceled"].includes(z(e)),L=(...e)=>{const n=e.find(o=>o!=null&&o!=="");return typeof n=="string"||typeof n=="number"?String(n):""},ke=e=>!!e&&!["null","undefined"].includes(e.toLowerCase()),Se=e=>e?L(e.payment_status).trim().toLowerCase()==="confirmed":!1,H=e=>e?L(e.payment_method).trim().toLowerCase()==="cash":!1,W=e=>["cash","offline","pay_on_checkin","pay-on-checkin","pay on check-in"].includes(e.trim().toLowerCase()),_e=e=>L(e?.payment_url).trim(),$=async e=>{const n=await fetch(`${P}/reservation/${encodeURIComponent(e)}`,{cache:"no-store",headers:{"ngrok-skip-browser-warning":"true"}}),o=await n.json();return n.ok&&o.data?o.data:null},Ce=async e=>{if(!(await fetch(`${P}/reservation/${encodeURIComponent(e)}/payment-method`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"},body:JSON.stringify({payment_method:"pesapal"})})).ok)throw new Error("Unable to update payment method.")},R=e=>{if(!e)return"";const n=H(e),o=String(e.refund_pending?"Refund Pending":e.payment_status??"awaiting_payment").toLowerCase(),h=String(e.confirmation_status??e.status??"pending").toLowerCase();return o==="refund pending"?"Your payment was received, but the club cannot honor this reservation. A refund review is pending and the team will follow up with the next steps.":o==="awaiting_payment"?n?"Your reservation request has been sent. The club will review availability and you can settle directly with the club as arranged.":"Your reservation request has been created, but payment is still required before the club can review and confirm it.":h==="pending"&&o==="confirmed"?"Your payment is confirmed. The club is now reviewing availability and will confirm the reservation or contact you if it cannot be honored.":h==="pending"?"Your reservation request is pending review. The club will confirm availability before your booking is final.":h==="confirmed"?"Your reservation is confirmed. Please keep this page or your reservation code for check-in.":h==="cancelled"?o==="confirmed"?"This reservation has been cancelled after payment. The refund process is pending review.":"This reservation has been cancelled. No further action is needed unless you would like to make a new booking.":h==="refunded"?"This reservation was cancelled and the payment has been refunded.":"Your reservation details are available below."};function Ne(e){const n={type:A,timestamp:new Date().toISOString(),...e};if(window.parent?.postMessage(n,window.location.origin),window.opener?.postMessage(n,window.location.origin),localStorage.setItem(A,JSON.stringify(n)),"BroadcastChannel"in window){const o=new BroadcastChannel(A);o.postMessage(n),o.close()}}function Re({searchParams:e}){const n=e.reservationId??e.ReservationId??e.reservation_id??e.reservation??"",o=e.paymentMethod??e.payment_method??e.method??"",[h,p]=d.useState("processing"),[j,i]=d.use
1State(W(o)?"Loading your reservation request...":"Confirming your payment..."),[c,g]=d.useState(null),[s,a]=d.useState("idle"),[M,b]=d.useState(""),[X,I]=d.useState(!1),[O,E]=d.useState(""),[Z,ee]=d.useState(0),[_,Y]=d.useState(n),S=d.useMemo(()=>e.OrderTrackingId??e.orderTrackingId??e.order_tracking_id??"",[e]),C=d.useMemo(()=>e.OrderMerchantReference??e.orderMerchantReference??e.merchantReference??"",[e]);d.useEffect(()=>{if(!S){const y=n;if(!y){p("failed"),i("Missing reservation details. Please contact the club.");return}let m=!1;return(async()=>{p("processing"),i("Loading your reservation details...");try{const f=await $(y);if(m)return;if(!f){p("failed"),i("Unable to find that reservation.");return}g(f),Y(f.reservation_id??y),p("success"),i(R(f))}catch{m||(p("failed"),i("Unable to load this reservation. Please contact the club."))}})(),()=>{m=!0}}if(!S)return;let l=!1;return(async()=>{try{const m=await(await fetch(`${P}/pesapal/status/${encodeURIComponent(S)}`,{cache:"no-store",headers:{"ngrok-skip-browser-warning":"true"}})).json();if(l)return;let x=null;const f=String(m.reservationId??m.reservation_id??m.merchantReference??C??_);if(f){Y(f);try{x=await $(f),!l&&x&&g(x)}catch{}}if(Ne({orderTrackingId:S,merchantReference:C,reservationId:f,status:z(m)}),we(m)){x&&i(R(x)),p("success"),f||i("Payment confirmed. The club will now review and confirm your reservation.");return}if(je(m)){if(x||c||f){p("success"),i("Payment failed or was cancelled. You can try paying again below.");return}p("failed"),i("Payment failed or was cancelled.");return}x||c||f?(p("success"),i("Payment is still not confirmed. You can open the payment window below.")):(p("processing"),i("Payment is still being confirmed. You may return to the reservation page."))}catch{l||(p("failed"),i("Unable to confirm this payment. Please contact the club."))}})(),()=>{l=!0}},[C,S,_,n]);const D=String(c?.history_status??""),te=D==="upcoming",v=c?.reservation_id??_,T=_e(c),k=H(c),F=k||W(o),q=ke(T),ne=!!c&&!F&&!Se(c),ae=k?"Pay Now Online":"Open Payment Window",se=F?"Reservation request sent":h==="success"?"Reservation Status":"Payment Confirmation",N=Number(c?.total_amount??0),B=c?.currency||"USD",re=new Intl.NumberFormat("en-US",{style:"currency",currency:B,minimumFractionDigits:0,maximumFractionDigits:2}).format(N),oe=async()=>{if(!(!v||s==="loading"||!window.confirm("Cancel this upcoming reservation?"))){a("loading"),b("");try{const U=await fetch(`${P}/reservation/${encodeURIComponent(v)}/cancel`,{method:"POST",headers:{"Content-Type":"application/json","ngrok-skip-browser-warning":"true"}}),y=await U.json();if(!U.ok||!y.success){a("error"),b(y.error||"Unable to cancel this reservation.");return}a("success"),b(y.message||"Reservation cancelled successfully."),g(m=>m&&{...m,status:"cancelled",payment_status:y.message?.toLowerCase().includes("refund")?"Refund Pending":m.payment_status,confirmation_status:"Cancelled",refund_pending:y.message?.toLowerCase().includes("refund")?!0:m.refund_pending,history_status:"cancelled"})}catch{a("error"),b("Unable to reach the server. Please try again later.")}}},ie=()=>{if(k||!q){I(!0),ee(l=>l+1);return}window.open(T,"_blank","noopener,noreferrer")},ce=async()=>{if(v){try{await Ce(v)}catch{E("Payment was confirmed, but the payment method could not be updated automatically.")}I(!1),g(l=>l&&{...l,payment_method:"pesapal",payment_status:"confirmed",confirmation_status:l.confirmation_status||"pending"});try{const l=await $(v);l&&(g(l),i(R(l)))}catch{i("Payment confirmed. The club will now review and confirm your reservation.")}}};return t.jsxs("div",{className:"min-h-screen bg-cream px-6 py-20",children:[t.jsxs("div",{className:"mx-auto mb-6 max-w-3xl border border-border bg-card px-6 py-5",children:[t.jsx("p",{className:"text-xs uppercase tracking-[0.3em] text-gold",children:"Payment Callback"}),t.jsx("h1",{className:"mt-2 font-serif text-3xl text-forest",children:se}),t.jsx("p",{className:"mt-2 text-sm text-muted-foreground",children:j})]}),h==="success"?t.jsxs(t.Fragment,{children:[t.jsx(ve,{reservationCode:c?"":_||C,reservation:c,compact:!0}),c&&t.jsxs("div",{className:"mx-auto mt-6 max-w-3xl border border-border bg-card px-6 py-6",children:[t.jsx("div",{className:"mb-5 border border-gold/40 bg-gold/10 px-4 py-3 text-sm text-forest",children:R(c)}),M&&t.jsx("p",{className:`mb-4 border px-4 py-3 text-sm ${s==="error"?"border-destructive/30 bg-destructive/5 text-destructive":"border-gold/40 bg-gold/10 text-forest"}`,children:M}),ne&&t.jsx("div",{className:"mb-5 border border-forest/30 bg-cream px-4 py-4",children:t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("div",{children:[t.jsx("p",{className:"text-xs uppercase tracking-[0.24em] text-muted-foreground",children:k?"Payment Method: Cash":"Payment Required"}),t.jsx("p",{className:"mt-1 text-sm text-forest",children:k?"You chose cash payment. You can switch to online payment and pay right now to confirm your reservation.":"Your reservation cannot be confirmed until payment is completed. Open the payment window to pay now."})]}),t.jsxs("button",{type:"button",onClick:ie,className:"inline-flex items-center justify-center gap-2 border border-forest px-5 py-3 text-xs uppercase tracking-[0.22em] text-forest transition hover:bg-forest hover:text-cream",children:[t.jsx(he,{size:14}),ae]})]})}),O&&t.jsx("p",{className:"mb-4 border border-destructive/30 bg-destructive/5 px-4 py-3 text-sm text-destructive",children:O}),X&&c&&v&&N>0&&t.jsx(pe,{amountUsd:N,chargeAmount:N,chargeCurrency:B,formattedChargeAmount:re,reservationId:v,bookingDetails:{email:c.email??"",phoneNumber:c.phone,firstName:c.first_name,lastName:c.last_name},initialCheckoutUrl:q&&!k?T:"",maximizeRequestId:Z,onSuccess:ce,onAwaitingConfirmation:l=>i(l),onCancel:()=>I(!1),onError:E}),te?t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:justify-end",children:[t.jsx(fe,{}),t.jsx("button",{type:"button",onClick:oe,disabled:s==="loading",className:"border border-destructive/50 px-5 py-3 text-xs uppercase tracking-[0.22em] text-destructive transition hover:bg-destructive hover:text-destructive-foreground disabled:cursor-not-allowed disabled:opacity-60",children:s==="loading"?"Cancelling...":"Cancel Reservation"})]}):t.jsxs("p",{className:"text-sm text-muted-foreground",children:["This reservation is",D||"not upcoming"," ","and cannot be cancelled online."]})]})]}):t.jsx("div",{className:"mx-auto max-w-3xl border border-border bg-card px-6 py-6 text-sm text-muted-foreground",children:"Keep this page open while the payment result is verified. If you came from the payment modal, the reservation page will update automatically."})]})}function Ee(){const e=me({from:"/payment_/callback"});return t.jsx(Re,{searchParams:e})}export{Ee as component};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.