KISA 제보 취약점(KVE-2026-1914/1919/2019/2029/2041/2042/2043/2044)과 그 수정 과정에서 드러난 자격증명 전송로 결함을 함께 해소한다. globalHeaders 는 데이터소스와 apiCall 핸들러에만 적용되는데, 코어 ApiClient 를 직접 부르는 경로들이 그 사실을 모른 채 게이트된 엔드포인트를 호출하고 있었다. 서버는 정당한 사용자를 거부하고 화면은 이미 버튼을 내준 뒤라, 예외도 로그도 없이 그 자리만 비는 형태로만 드러났다. 전송로 10축을 전수 열거해 6건을 고치고, 같은 실수가 반복되지 않도록 규정과 coverage 에 등재했다. 아웃바운드 프록시가 사이트 자기 자신으로 가는 내부 요청까지 가로채 저장이 수십 초씩 걸리던 문제도 함께 고쳤다. 실패가 폴백으로 삼켜져 화면에는 지연으로만 나타났다.
2 lines
25 KiB
JavaScript
2 lines
25 KiB
JavaScript
(function(){"use strict";function de(e){return/^https?:\/\//i.test(e)||e.startsWith("/api/")?e:e.startsWith("/plugins/")?`/api${e}`:e.startsWith("plugins/")?`/api/${e}`:e}function ue(e){return e.trim().slice(0,160)}async function pe(e,t="nicepay-window-closed"){if(!e.closeReportUrl)return;const n={oid:e.oid,price:Number(e.price),buyer_email:e.buyer_email??"",buyer_phone:e.buyer_phone??"",payment_method:e.payment_method??"",reason:ue(t)||"nicepay-window-closed"};try{const a=window.G7Core?.api;if(typeof a?.post=="function"){await a.post(e.closeReportUrl,n);return}await fetch(de(e.closeReportUrl),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),keepalive:!0})}catch(a){console.warn("[sirsoft-pay_nicepayments] failed to report payment window close",a)}}const me=["web.nicepay.co.kr"];function ye(e,t){const n=window?.G7Core?.t;if(typeof n!="function")return t;const a=`sirsoft-pay_nicepayments.${e}`,r=n(a);return typeof r=="string"&&r!==a?r:t}function fe(e){let t=null;try{t=new URL(e)}catch{t=null}if(t===null||t.protocol!=="https:"||!me.includes(t.hostname.toLowerCase()))throw new Error(ye("payment.error.sdk_url_untrusted","결제 모듈 주소가 올바르지 않아 결제를 진행할 수 없습니다."))}async function he(e){if(fe(e),typeof window.goPay=="function")return;document.querySelectorAll(`script[src="${CSS.escape(e)}"]`).forEach(n=>n.remove());const t=window?.G7Core?.asset?.loadScript;if(typeof t=="function"){await t(e,{},{label:"nicepayments SDK"});return}await new Promise((n,a)=>{const r=document.createElement("script");r.src=e,r.onload=()=>n(),r.onerror=()=>a(new Error(`Failed to load script: ${e}`)),document.head.appendChild(r)})}function ge(e,t){const n=document.createElement("form");n.id="nicepayForm",n.method="post",n.action=e,n.acceptCharset="utf-8";for(const[a,r]of Object.entries(t)){const o=document.createElement("input");o.type="hidden",o.name=a,o.value=r,n.appendChild(o)}return document.body.appendChild(n),n}const we="/plugins/sirsoft-pay_nicepayments/payment/callback",be="https://web.nicepay.co.kr/v3/v3Payment.jsp";function _e(){if(typeof navigator>"u")return!1;const e=navigator;if(e.userAgentData?.mobile!==void 0)return e.userAgentData.mobile;const t=(navigator.userAgent||"").toLowerCase();return!!(/android|iphone|ipod|windows phone|iemobile|blackberry|opera mini|mobile safari/.test(t)||(navigator.maxTouchPoints??0)>1&&!t.includes("windows")&&!t.includes("macintosh"))}async function Pe(e,t){const{pgPaymentData:n,paymentMethod:a}=e.params??{},r=window.__templateApp?.globalState?._local,o=a??n?.payment_method??r?.paymentMethod??"card";if(!n){console.error("[sirsoft-pay_nicepayments] pgPaymentData is required");return}const i=window.G7Core;try{const s=await i.api.get("/modules/sirsoft-ecommerce/payments/client-config/nicepayments");if(!s.data){console.error("[sirsoft-pay_nicepayments] Failed to fetch client config",s);return}const l=s.data,d=_e();if(!d&&(await he(l.sdk_url),typeof window.goPay!="function")){i?.toast?.error?.("나이스페이먼츠 SDK를 불러올 수 없습니다. 잠시 후 다시 시도해주세요."),i?.state?.setLocal?.({isSubmittingOrder:!1,paymentMethod:o});return}const _=window.location.origin+l.sign_data_url,u=typeof localStorage<"u"?localStorage.getItem("auth_token"):null,te={"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest",Accept:"application/json"};u&&(te.Authorization=`Bearer ${u}`);const ne=await fetch(_,{method:"POST",credentials:"include",headers:te,body:JSON.stringify({amt:n.amount,moid:n.order_number,buyer_email:n.customer_email??"",buyer_phone:n.customer_phone??""})});if(!ne.ok)throw new Error("SignData 생성에 실패했습니다.");const M=await ne.json(),ae=window.location.origin+we,D=typeof o=="string"&&o.startsWith("nicepay_"),oe=D?"CARD":{card:"CARD",vbank:"VBANK",bank:"BANK",phone:"CELLPHONE"}[o??"card"]??"CARD",c={PayMethod:oe,GoodsName:n.order_name,Amt:String(n.amount),MID:M.mid,Moid:n.order_number,BuyerName:n.customer_name??"",BuyerEmail:n.customer_email??"",BuyerTel:n.customer_phone??"",ReturnURL:ae,EdiDate:M.ediDate,SignData:M.signData,CharSet:"utf-8",GoodsCl:"1",DirectShowOpt:"",DirectEasyPay:"",NicepayReserved:"",EasyPayMethod:"",MallReserved:"",MallReserved1:""};oe==="CELLPHONE"&&(c.GoodsCl=n.goods_cl??"1");const _t=l.useEscrow&&!D;if(c.TransType=_t?"1":"0",D)switch(c.DirectShowOpt="CARD",c.MallReserved=`nicepay_easy_pay_method=${encodeURIComponent(o)}`,c.MallReserved1=o,o){case"nicepay_naverpay":c.DirectEasyPay="E020",c.EasyPayMethod="E020=CARD";break;case"nicepay_kakaopay":c.NicepayReserved="DirectKakao=Y";break;case"nicepay_samsungpay":c.DirectEasyPay="E021";break;case"nicepay_applepay":c.DirectEasyPay="E025";break;case"nicepay_payco":c.NicepayReserved="DirectPayco=Y";break;case"nicepay_skpay":c.NicepayReserved="DirectPay11=Y";break;case"nicepay_ssgpay":c.DirectEasyPay="E007";break;case"nicepay_lpay":c.DirectEasyPay="E018";break}try{const m=i?.state?.get?.("_global")?.guestOrderToken,f=(await i.api.get(`/modules/sirsoft-ecommerce/user/orders/${n.order_number}`,m?{headers:{"X-Guest-Order-Token":m}}:void 0))?.data;if(f){const h=Number(f.total_tax_amount??0),ce=Number(f.total_vat_amount??0),le=Number(f.total_tax_free_amount??0);(h>0||ce>0||le>0)&&(c.TaxAmt=String(h),c.VatAmt=String(ce),c.TaxFreeAmt=String(le))}}catch{}const p=ge(ae,c);if(d){p.action=be,p.acceptCharset="euc-kr";const m=p.querySelector('input[name="CharSet"]');m&&(m.value="euc-kr"),p.submit();return}window.nicepaySubmit=()=>{p.submit()};let re=!1;const Pt=new Set(document.body.children),ie=(m,P)=>{if(re)return;re=!0;const f=[m,P].filter(Boolean).join(": ")||"nicepay-window-closed";pe({closeReportUrl:l.close_report_url,oid:n.order_number,price:Number(n.amount),buyer_email:n.customer_email??"",buyer_phone:n.customer_phone??"",payment_method:o},f),window.removeEventListener("popstate",se),Array.from(document.body.children).forEach(h=>{Pt.has(h)||h.remove()}),p.parentNode&&p.parentNode.removeChild(p),window.__sirsoftNicepayPaymentInProgress=!1,i?.state?.setLocal?.({isSubmittingOrder:!1,paymentMethod:o}),P&&i?.toast?.error?.(P)};window.nicepayClose=ie;const se=()=>ie("","");window.history.pushState({nicepayOpen:!0},""),window.addEventListener("popstate",se),window.goPay(p)}catch(s){console.error("[sirsoft-pay_nicepayments] requestPayment error",s),window.__sirsoftNicepayPaymentInProgress=!1,i?.state?.setLocal?.({isSubmittingOrder:!1,paymentMethod:o}),i?.toast?.error?.("결제 중 오류가 발생했습니다. 잠시 후 다시 시도해주세요.")}}const Ce={nicepay_naverpay:"네이버페이",nicepay_kakaopay:"카카오페이",nicepay_samsungpay:"삼성페이",nicepay_applepay:"애플페이",nicepay_payco:"PAYCO",nicepay_skpay:"11pay",nicepay_ssgpay:"SSG페이",nicepay_lpay:"L.pay"},Se="0 0 0 2px #ffffff, 0 0 0 5px rgba(0,0,0,0.55)";function R(){const e=document.getElementById("nicepay_checkout_payment_section");if(!e)return null;const t=e.querySelectorAll("p");for(const n of t)if(n.textContent?.includes("간편결제"))return n.nextElementSibling;return null}function T(){const e=R();e&&e.querySelectorAll("button").forEach(t=>{t.style.boxShadow="",t.style.outline=""})}function Ee(e){const t=R();if(!t)return;const n=Ce[e];t.querySelectorAll("button").forEach(a=>{a.textContent?.trim()===n?(a.style.boxShadow=Se,a.style.outline="none"):(a.style.boxShadow="",a.style.outline="")})}function xe(e){const t=e.params?.paymentMethod;if(!t)return;const n=typeof t=="string"&&t.indexOf("nicepay_")===0;window.G7Core?.state?.setLocal?.({paymentMethod:t}),n?Ee(t):T()}function $(){const e=window.__templateApp;typeof e?.onGlobalStateChange=="function"&&e.onGlobalStateChange(t=>{const n=t?._local?.paymentMethod;typeof n=="string"&&(n.startsWith("nicepay_")||T())})}const O={requestPayment:Pe,setPaymentMethod:xe},Ne="sirsoft-pay_nicepayments",ke={info:(...e)=>console.info(`[${Ne}]`,...e)};function Ae(){ke.info("order interceptor is a no-op — payment entry is dispatched via pg_payment_handler")}function ve(){return localStorage.getItem("auth_token")}function Le(){try{const t=sessionStorage.getItem("g7_guest_order_token");if(t)return t}catch{}const e=window.G7Core?.state?.get?.("_global")?.guestOrderToken;return typeof e=="string"&&e!==""?e:null}function C(){const e=ve(),t=Le();if(!e&&!t)return null;const n={Accept:"application/json"};return e?n.Authorization=`Bearer ${e}`:t&&(n["X-Guest-Order-Token"]=t),n}const S="sirsoft-pay_nicepayments",B="__nicepayOcReceiptInjectorInstalled",j="nicepay-oc-receipt-btn",Ie=/^\/shop\/orders\/([^/]+)\/complete$/;async function Me(e){const t=C();if(!t)return null;try{const n=await fetch(`/api/modules/sirsoft-ecommerce/user/orders/${e}`,{headers:t,credentials:"same-origin"});return n.ok?(await n.json())?.data?.payment??null:null}catch{return null}}async function G(e){const t=C();if(!t)return null;try{const n=await fetch(`/api/plugins/${S}/user/orders/${e}/receipt`,{headers:t,credentials:"same-origin"});return n.ok?await n.json():null}catch{return null}}function De(e){if(!e)return!1;const t=Array.from(document.querySelectorAll("div"));for(const n of t){const a=Array.from(n.children).filter(i=>i instanceof HTMLElement&&i.tagName==="SPAN");if(a.length<2)continue;const r=a[0].textContent?.trim();if(r!=="결제 방법"&&r!=="결제수단"&&r!=="결제 방식")continue;const o=a[a.length-1];return o.textContent?.trim()!==e&&(o.textContent=e,o.dataset.nicepayPaymentMethodPatched="true"),n.dataset.nicepayPaymentMethodRow="true",!0}return!1}async function Re(e){if(document.getElementById(j))return;const t=await Me(e);if(!t||t.pg_provider!=="nicepayments"||!t.transaction_id||!t.paid_at)return;const n=Array.from(document.querySelectorAll('button[type="button"]')).find(s=>s.className.includes("bg-blue-600"));if(!n?.parentElement)return;const a=await G(e);De(a?.payment_method_display_label);const r=n.parentElement,o=document.createElement("button");o.id=j,o.type="button",o.className=n.className.replace(/bg-blue-\d+/g,"bg-green-600").replace(/hover:bg-blue-\d+/g,"hover:bg-green-700"),o.textContent="영수증 조회",o.addEventListener("click",async()=>{o.disabled=!0,o.textContent="로딩 중...";const s=await G(e);o.disabled=!1,o.textContent="영수증 조회";const l=s?.receipt_url??null;l&&window.open(l,"nicepay_receipt","width=800,height=600,scrollbars=yes,resizable=yes")});const i=r.lastElementChild;r.insertBefore(o,i),console.info(`[${S}] receipt button injected on order complete page`)}function Te(){const e=location.pathname.match(Ie);e&&Re(e[1])}function $e(){if(typeof window>"u")return;const e=window;if(e[B])return;e[B]=!0,console.info(`[${S}] order complete receipt injector installed`);const t=(a=1200)=>setTimeout(Te,a);document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>t()):t();const n=history.pushState.bind(history);history.pushState=(...a)=>{n(...a),t()},window.addEventListener("popstate",()=>t(500))}const g="sirsoft-pay_nicepayments",H="__nicepayOrderShowInjectorInstalled",q="nicepay-mp-receipt-row",U="nicepay-mp-vbank-info",Oe=/^(?:\/mypage\/orders\/([^/]+)|\/shop\/guest\/orders\/([^/]+))$/;function Be(e){try{const n=window.G7Core?.getState,o=n?.()?.currentDataContext?.order?.data;return!o||o.order_number!==e?null:o}catch{return null}}async function F(e){const t=C();if(!t)return null;try{const n=await fetch(`/api/plugins/${g}/user/orders/${e}/receipt`,{headers:t,credentials:"same-origin"});return n.ok?await n.json():null}catch{return null}}function je(e,t){if(!t)return!1;const n=Array.from(e.querySelectorAll("div"));for(const a of n){const r=Array.from(a.children).filter(s=>s instanceof HTMLElement&&s.tagName==="SPAN");if(r.length<2)continue;const o=r[0].textContent?.trim();if(o!=="결제 방법"&&o!=="결제수단"&&o!=="Payment Method")continue;const i=r[r.length-1];return i.textContent?.trim()!==t&&(i.textContent=t,i.dataset.nicepayPaymentMethodPatched="true"),a.dataset.nicepayPaymentMethodRow="true",!0}return!1}function Ge(){const e=document.getElementById("order_payment_info_panel");if(e)return Array.from(e.children).find(a=>a.className?.includes("space-y"))??e;const t=Array.from(document.querySelectorAll("h3")).find(a=>a.textContent?.includes("결제 정보"));if(!t)return null;const n=t.parentElement?.parentElement;return n?Array.from(n.children).find(a=>a.className?.includes("space-y"))??n:null}function He(e){const t=document.createElement("div");t.id=q,t.className="flex items-center justify-between";const n=document.createElement("span");n.className="text-gray-500 dark:text-gray-400 text-sm",n.textContent="영수증";const a=document.createElement("button");return a.type="button",a.className="inline-flex items-center gap-1 text-sm text-blue-600 dark:text-blue-400 hover:underline disabled:opacity-50",a.textContent="영수증 조회",a.addEventListener("click",async()=>{a.disabled=!0,a.textContent="로딩 중...";const r=await F(e);a.disabled=!1,a.textContent="영수증 조회";const o=r?.receipt_url??null;o&&window.open(o,"nicepay_receipt","width=800,height=600,scrollbars=yes,resizable=yes")}),t.appendChild(n),t.appendChild(a),t}function qe(e){if(!e)return"";try{const t=new Date(e);if(Number.isNaN(t.getTime()))return e;const n=a=>String(a).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}:${n(t.getSeconds())}`}catch{return e}}function w(e,t,n="font-medium text-gray-900 dark:text-white"){const a=document.createElement("div");a.className="flex justify-between text-sm";const r=document.createElement("span");r.className="text-gray-600 dark:text-gray-400",r.textContent=e;const o=document.createElement("span");return o.className=n,o.textContent=t,a.appendChild(r),a.appendChild(o),a}function Ue(e){const t=e.payment??{},n=document.createElement("div");n.id=U,n.className="pt-4 mt-2 border-t border-gray-200 dark:border-gray-700";const a=document.createElement("div");a.className="bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-700 rounded-lg p-4";const r=document.createElement("h3");r.className="text-sm font-semibold text-blue-800 dark:text-blue-300 mb-3",r.textContent="가상계좌 입금 안내";const o=document.createElement("div");o.className="space-y-2",o.appendChild(w("은행",t.vbank_name??"")),o.appendChild(w("계좌번호",t.vbank_number??"","font-medium font-mono text-gray-900 dark:text-white")),o.appendChild(w("예금주",t.vbank_holder??"")),o.appendChild(w("입금 금액",e.total_amount_formatted??"","font-bold text-blue-600 dark:text-blue-400"));const i=t.vbank_due_at;if(i){const s=document.createElement("div");s.className="flex justify-between text-sm pt-2 border-t border-blue-200 dark:border-blue-700 mt-2";const l=document.createElement("span");l.className="text-gray-600 dark:text-gray-400",l.textContent="입금 기한";const d=document.createElement("span");d.className="font-medium text-red-600 dark:text-red-400",d.textContent=qe(i),s.appendChild(l),s.appendChild(d),o.appendChild(s)}if(a.appendChild(r),a.appendChild(o),!t.paid_at){const s=document.createElement("p");s.className="text-xs text-blue-700 dark:text-blue-300 mt-3",s.textContent="입금 기한 내에 입금이 완료되지 않으면 주문이 자동 취소됩니다.",a.appendChild(s)}return n.appendChild(a),n}async function Fe(e){const t=Be(e);if(!t)return!1;const{payment:n}=t;if(!n||n.pg_provider!=="nicepayments")return!0;const a=Ge();if(!a)return!1;const r=await F(e);return je(a,r?.payment_method_display_label),n.payment_method==="vbank"&&n.vbank_number&&!document.getElementById(U)&&(a.appendChild(Ue(t)),console.info(`[${g}] vbank info injected on mypage order show`)),!n.transaction_id||!n.paid_at||document.getElementById(q)||(a.appendChild(He(e)),console.info(`[${g}] receipt button injected on mypage order show`)),!0}function We(e){let t=0;const n=setInterval(()=>{t++,Fe(e).then(a=>{(a||t>=30)&&clearInterval(n)})},400)}function Ye(){const e=location.pathname.match(Oe),t=e?.[1]??e?.[2];t&&We(t)}function Ke(){if(typeof window>"u")return;const e=window;if(e[H])return;e[H]=!0,console.info(`[${g}] mypage order show injector installed`);const t=(a=1500)=>setTimeout(Ye,a);document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>t()):t();const n=history.pushState.bind(history);history.pushState=(...a)=>{n(...a),t(600)},window.addEventListener("popstate",()=>t(500))}const Ve="sirsoft-pay_nicepayments",W="__nicepayAdminPaymentMethodBrandInjectorInstalled",Y="__nicepayAdminPaymentMethodBrandSyncListenerAttached",ze=/^\/admin\/ecommerce\/settings\/?$/,K='[data-nicepay-admin-payment-brand-mark="true"]',Xe=200,Je=120,Qe=[{id:"nicepay_naverpay",labels:["네이버페이 (나이스페이먼츠)","네이버페이로 결제 (나이스페이먼츠)","Naver Pay (NicePayments)","Pay with Naver Pay (NicePayments)"],shortLabels:[],markLines:["N"],markClassName:"bg-green-500 text-white"},{id:"nicepay_kakaopay",labels:["카카오페이 (나이스페이먼츠)","카카오페이로 결제 (나이스페이먼츠)","Kakao Pay (NicePayments)","Pay with Kakao Pay (NicePayments)"],shortLabels:[],markLines:["K"],markClassName:"bg-yellow-400 text-gray-950"},{id:"nicepay_samsungpay",labels:["삼성페이 (나이스페이먼츠)","삼성페이로 결제 (나이스페이먼츠)","Samsung Pay (NicePayments)","Pay with Samsung Pay (NicePayments)"],shortLabels:[],markLines:["S"],markClassName:"bg-blue-600 text-white"},{id:"nicepay_applepay",labels:["애플페이 (나이스페이먼츠)","애플페이로 결제 (나이스페이먼츠)","Apple Pay (NicePayments)","Pay with Apple Pay (NicePayments)"],shortLabels:[],markLines:["A"],markClassName:"bg-gray-900 text-white"},{id:"nicepay_payco",labels:["PAYCO (나이스페이먼츠)","PAYCO로 결제 (나이스페이먼츠)","PAYCO (NicePayments)","Pay with PAYCO (NicePayments)"],shortLabels:[],markLines:["P"],markClassName:"bg-red-500 text-white"},{id:"nicepay_skpay",labels:["11pay (나이스페이먼츠)","11pay로 결제 (나이스페이먼츠)","11pay (NicePayments)","Pay with 11pay (NicePayments)"],shortLabels:[],markLines:["11"],markClassName:"bg-orange-500 text-white"},{id:"nicepay_ssgpay",labels:["SSG페이 (나이스페이먼츠)","SSG페이로 결제 (나이스페이먼츠)","SSG Pay (NicePayments)","Pay with SSG Pay (NicePayments)"],shortLabels:[],markLines:["SSG"],markClassName:"bg-red-700 text-white"},{id:"nicepay_lpay",labels:["L.pay (나이스페이먼츠)","L.pay로 결제 (나이스페이먼츠)","L.pay (NicePayments)","Pay with L.pay (NicePayments)"],shortLabels:[],markLines:["L"],markClassName:"bg-purple-600 text-white"}];let V=null,b=null,E=!1;function Ze(){return window}function x(){if(!ze.test(window.location.pathname))return!1;const e=new URLSearchParams(window.location.search).get("tab");return e===null||e===""||e==="order_settings"}function et(e){return e instanceof HTMLElement?e.className:""}function z(e){return(e??"").replace(/\u200B/g,"").replace(/\s+/g," ").trim()}function tt(e){const t=et(e);return t.includes("excel-card")||t.includes("flex-center")&&t.includes("border")&&t.includes("gap-4")}function X(e){return e.querySelector(".font-medium")}function nt(e){const t=z(X(e)?.textContent),n=z(e.textContent);return Qe.find(a=>a.shortLabels.some(r=>t===r)||a.labels.some(r=>n.includes(r)))??null}function at(e){return Array.from(e.querySelectorAll("div")).filter(tt)}function ot(e){return Array.from(e.querySelectorAll("svg, [data-icon], i")).find(n=>!n.closest("[data-drag-handle]")&&!n.closest(K)&&!n.closest('.row-stack, .excel-card-body, button, select, [role="switch"]'))??null}function J(e,t){e.dataset.nicepayAdminPaymentBrandMark="true",e.dataset.nicepayAdminPaymentMethod=t.id,e.setAttribute("aria-hidden","true"),e.className=`inline-flex items-center justify-center rounded-lg font-bold ${t.markClassName}`,e.style.width="32px",e.style.height="32px",e.style.flex="0 0 32px",e.style.lineHeight="1",e.style.fontSize=t.markLines.join("").length>2?"9px":"12px";const n=t.markLines.join("");e.textContent!==n&&(e.textContent=t.markLines[0]??"")}function rt(e){const t=document.createElement("span");return J(t,e),t}function it(e,t){const n=e.querySelector(K);if(n instanceof HTMLSpanElement)return e.dataset.nicepayAdminPaymentMethod=t.id,J(n,t),!0;const a=rt(t),r=ot(e);if(r&&r.parentElement)return e.dataset.nicepayAdminPaymentMethod=t.id,r.replaceWith(a),!0;const o=X(e);return o&&o.parentElement?(e.dataset.nicepayAdminPaymentMethod=t.id,o.parentElement.insertBefore(a,o),!0):!1}function N(e=document){if(typeof window>"u"||typeof document>"u"||!x())return!1;let t=!1;return at(e).forEach(n=>{const a=nt(n);a&&it(n,a)&&(t=!0)}),t}function st(){E||(E=!0,window.setTimeout(()=>{E=!1,N()},0))}function k(){b!==null&&(window.clearInterval(b),b=null)}function A(){if(!x())return;k(),N();let e=0;b=window.setInterval(()=>{e+=1,N(),e>=Je&&k()},Xe);const t=document.body;t[Y]||(t[Y]=!0,V=new MutationObserver(()=>st()),V.observe(document.body,{childList:!0,subtree:!0,characterData:!0}))}function v(){if(x()){A();return}k()}function ct(){if(typeof window>"u"||typeof document>"u")return;const e=Ze();if(e[W])return;e[W]=!0,console.info(`[${Ve}] admin payment method brand sync installed`),document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>A()):A();const t=history.pushState.bind(history);history.pushState=(...a)=>{t(...a),window.setTimeout(()=>v(),200)};const n=history.replaceState.bind(history);history.replaceState=(...a)=>{n(...a),window.setTimeout(()=>v(),200)},window.addEventListener("popstate",()=>window.setTimeout(()=>v(),200))}const L="sirsoft-pay_nicepayments",Q="__nicepayAdminPaymentDisplayInjectorInstalled",lt=/^\/admin\/ecommerce\/orders\/([^/]+)$/;function dt(){return localStorage.getItem("auth_token")}async function ut(e){const t=dt();if(!t)return null;try{const n=await fetch(`/api/plugins/${L}/admin/orders/${e}/transaction-status`,{headers:{Authorization:`Bearer ${t}`,Accept:"application/json"}});if(!n.ok)return null;const a=await n.json();return("data"in a?a.data:a)??null}catch{return null}}function pt(e){return Array.from(e.children).filter(t=>t instanceof HTMLElement)}function mt(e,t){let n=!1;const a=Array.from(e.querySelectorAll("div"));for(const r of a){const o=pt(r),i=o.findIndex(u=>u.textContent?.trim()==="결제수단");if(i<0)continue;const s=o.slice(i+1).find(u=>u.textContent?.trim()&&u.textContent.trim()!=="결제수단");if(!s)continue;const l=o.slice(i+2).find(u=>/^\(.+\)$/.test(u.textContent?.trim()??"")),d=l?.textContent?.trim().replace(/^\(|\)$/g,"")??"",_=d&&t.endsWith(")")?t.replace(/\)$/,`, ${d})`):t;s.textContent?.trim()!==_&&(s.textContent=_,s.dataset.nicepayPaymentMethodPatched="true"),r.dataset.nicepayPaymentMethodRow="admin-order",l&&d&&(l.textContent="",l.style.display="none",l.dataset.nicepayPaymentInstallmentHidden="true"),n=!0}return n}function yt(e,t,n){const r=Array.from(e.querySelectorAll("span")).filter(o=>o.textContent?.trim()===t).find(o=>{const i=typeof o.className=="string"?o.className:"";return i.includes("rounded-full")||i.includes("font-medium")});return r?(r.textContent=n,r.dataset.nicepayPaymentMethodPatched="true",r.dataset.nicepayPaymentMethodBadge="admin-order",!0):!1}function ft(e,t){const n=t?._pay_method_label,a=t?._embedded_pg_provider_label,r=t?._base_pay_method_label;if(!n||!a)return!1;const o=mt(e,n),i=r?yt(e,r,a):!1;return o||i}async function ht(e){const t=document.getElementById("section_payment_info")??document.getElementById("payment_info_card");if(!t)return!1;const n=await ut(e);return n&&ft(t,n)&&console.info(`[${L}] payment method display patched on admin order detail`),!0}function gt(e){let t=0;const n=setInterval(()=>{t++,ht(e).then(a=>{(a||t>=30)&&clearInterval(n)})},400)}function wt(){const e=location.pathname.match(lt);e&>(e[1])}function bt(){if(typeof window>"u")return;const e=window;if(e[Q])return;e[Q]=!0,console.info(`[${L}] admin order payment display injector installed`);const t=(a=1500)=>setTimeout(wt,a);document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>t()):t();const n=history.pushState.bind(history);history.pushState=(...a)=>{n(...a),t(600)},window.addEventListener("popstate",()=>t(500))}const y="sirsoft-pay_nicepayments",I={info:(...e)=>console.info(`[${y}]`,...e),warn:(...e)=>console.warn(`[${y}]`,...e),error:(...e)=>console.error(`[${y}]`,...e)};function Z(){const e=window.G7Core;if(!e)return 0;const t=e.getActionDispatcher;if(typeof t!="function")return 0;const n=t();if(!n||typeof n.registerHandler!="function")return 0;let a=0;for(const[r,o]of Object.entries(O)){const i=`${y}.${r}`;n.registerHandler(i,o,{category:"plugin",source:y}),a++}return a}function ee(){Ae(),$e(),Ke(),ct(),bt();const e=()=>{const t=Z();if(t>0){I.info(`${t} handler(s) registered`),$();return}let n=0;const a=50,r=setInterval(()=>{n++;const o=Z();if(o>0){clearInterval(r),I.info(`${o} handler(s) registered (after ${n} retries)`),$();return}n>=a&&(clearInterval(r),I.warn("ActionDispatcher not available after timeout"))},100)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}ee(),window.__SirsoftNicepayments={identifier:y,handlers:Object.keys(O),initPlugin:ee}})();
|