function obidSpec(pkg){ pkg=String(pkg||''); if(pkg==='ai.x.grok'||pkg==='ai.x.grok.bot') return {label:'SSO', hint:'grok.com 的 sso cookie / JWT', mode:'grok'}; if(pkg==='com.anysphere.cursor') return {label:'用户 ID', hint:'Cursor 用户 ID,原值作为 obfuscatedAccountId', mode:'raw'}; if(pkg==='com.twitter.android') return {label:'用户 ID', hint:'X 用户 ID,原值作为 obfuscatedAccountId', mode:'raw'}; if(pkg==='com.anthropic.claude') return {label:'Session Key', hint:'sk- 开头的 sessionKey,购买时解析 Organization ID 和 Account UUID', mode:'claude'}; if(pkg==='com.discord') return {label:'用户 Authorization', hint:'Discord token,先解出用户 ID 再 SHA-256 hex', mode:'discord'}; if(pkg==='com.openai.chatgpt') return {label:'用户 ID', hint:'ChatGPT 用户 ID,SHA-256 Base64', mode:'b64'}; return null; } async function sha256Bytes(text){ const data=new TextEncoder().encode(String(text||'')); const buf=await crypto.subtle.digest('SHA-256', data); return new Uint8Array(buf); } function discordUserId(token){ token=String(token||'').trim(); const part=token.split('.')[0].replace(/=+$/,'').replace(/-/g,'+').replace(/_/g,'/'); if(!part) throw new Error('token 格式无效'); const pad=part+'='.repeat((4-part.length%4)%4); const id=atob(pad); if(!/^[0-9]+$/.test(id)) throw new Error('解码结果不是数字 user-id'); return id; } async function obidValue(mode, raw){ raw=String(raw||'').trim(); if(!raw) return {account:'', profile:''}; if(mode==='raw') return {account:raw, profile:''}; if(mode==='discord'){ const id=discordUserId(raw); const bytes=await sha256Bytes(id); return {account:[...bytes].map(b=>b.toString(16).padStart(2,'0')).join(''), profile:''}; } if(mode==='b64'){ const bytes=await sha256Bytes(raw); let s=''; bytes.forEach(b=>{ s+=String.fromCharCode(b); }); return {account:btoa(s), profile:''}; } if(mode==='grok'||mode==='claude'){ const j=await api('/api/purchases/obid',{method:'POST',body:JSON.stringify({package:mode==='grok'?'ai.x.grok':'com.anthropic.claude', input:raw, account_id:window._obidAccount||0})}); if(j.error) throw new Error(j.error); return {account:j.obfuscated_account_id||'', profile:j.obfuscated_profile_id||'', subscriptions:j.subscriptions||[]}; } return {account:raw, profile:''}; } function viewCards(){ const dock=document.getElementById('pagerDock'); const all=(cache.cards||[]).filter(c=>{ if(!c) return false; if(filters.cardHidden==='hidden' && !c.hidden) return false; if(filters.cardHidden!=='hidden' && filters.cardHidden!=='all' && c.hidden) return false; return matchQ([c.brand,c.scheme,c.type,c.bank,c.country,c.country_a2,c.last4,c.bin,c.pan,c.note,String(c.id)]); }); const info=paginate(all,'cards'); const rows=info.slice.map(c=>{ const exp=String(c.exp_month||'').padStart(2,'0')+'/'+String(c.exp_year||'').slice(-2); return ''+ '#'+c.id+''+ ''+esc(c.brand||c.scheme||'-')+'
'+esc([c.scheme,c.type,c.prepaid?'预付':''].filter(Boolean).join(' · '))+'
'+ ''+esc(cardPAN(c)||c.last4||'-')+''+ ''+esc(exp)+''+ ''+esc(c.bank||'-')+'
'+esc(countryLabel(c.country_a2||c.country||''))+'
'+ ''+(c.hidden?'已隐藏':'可用')+''+ ''+esc(c.note||'')+''+ ''+fmtTime(c.created_at)+''+ ' '+ ''; }).join(''); $('#app').innerHTML= '
'+ ''+ '隐藏的卡不会出现在绑卡和购买下拉里。订单卡尾号不在本卡库的订阅,升级重试并发固定为 1。'+ '
'+ '
'+ filterSelect('显示', 'filters.cardHidden=this.value; pageNo.cards=1; render(false)', '')+ '当前 '+all.length+' / '+(cache.cards||[]).length+''+ '
'+ '
'+ (rows||'')+ '
ID品牌卡号有效期发卡行状态备注入库
还没有卡。
'+pager('cards', info); if(dock && page!=='cards') dock.innerHTML=''; } function modalBusy(on, text){ const box=document.querySelector('#modalStack .modal')||document.querySelector('#modalRoot .modal'); if(!box) return; box.classList.toggle('busy', !!on); const ok=box.querySelector('#mOk'); if(ok){ if(on){ if(!ok.dataset.label) ok.dataset.label=ok.textContent; ok.disabled=true; ok.classList.add('busy'); ok.innerHTML=''+esc(text||'处理中'); }else{ ok.disabled=false; ok.classList.remove('busy'); if(ok.dataset.label) ok.textContent=ok.dataset.label; } } } async function addCardDlg(){ const root=$('#modalRoot'); root.innerHTML=''; const triple=$('#cardTriple'); const fill=()=>{ const got=parseCardTriple(triple.value); if(!got) return; $('#cardPan').value=got.pan; $('#cardExp').value=got.exp; $('#cardCvc').value=got.cvc; }; if(triple){ triple.addEventListener('input', fill); triple.addEventListener('paste', ()=>setTimeout(fill,0)); } const preview=async()=>{ const pan=($('#cardPan').value||'').replace(/\s/g,''); const exp=$('#cardExp').value.trim(); const cvc=$('#cardCvc').value.trim(); const box=$('#cardPreview'); if(pan.length<12){ if(box) box.textContent=''; return; } const j=await api('/api/cards/preview',{method:'POST',body:JSON.stringify({pan, exp, cvc})}); if(!box) return; if(j.error){ box.textContent=j.error; return; } box.textContent=[j.brand||j.scheme, j.type, j.bank, countryLabel(j.country_a2||j.country||''), j.prepaid?'预付':'', '尾号 '+(j.last4||'')].filter(Boolean).join(' · '); }; ['cardPan','cardExp','cardCvc'].forEach(id=>{ const el=$('#'+id); if(el) el.addEventListener('change', preview); }); const ok=await new Promise(resolve=>{ $('#mOk').onclick=()=>resolve(true); $('#mCancel').onclick=()=>resolve(false); bindMaskClose(root, ()=>resolve(false)); }); if(!ok){ root.innerHTML=''; return; } const pan=($('#cardPan').value||'').trim(); const exp=($('#cardExp').value||'').trim(); const cvc=($('#cardCvc').value||'').trim(); const note=($('#cardNote').value||'').trim(); const tripleText=(triple&&triple.value||'').trim(); modalBusy(true, '保存中'); const body=tripleText?{triple:tripleText, note}:{pan, exp, cvc, note}; const j=await api('/api/cards',{method:'POST',body:JSON.stringify(body)}); root.innerHTML=''; if(j.error) return fail('无法保存', j.error); notice('已保存', (j.brand||'卡')+' '+(j.last4||'')); await loadAll(); render(false); } async function setCardNoReplay(id, on){ const j=await api('/api/cards/'+id+'/no-replay',{method:'POST',body:JSON.stringify({no_replay_concurrency:!!on})}); if(j.error) return fail('无法保存', j.error); const card=(cache.cards||[]).find(c=>c && Number(c.id)===Number(id)); if(card) card.no_replay_concurrency=!!on; notice(on?'已禁止并发':'已允许并发', '尾号 '+((card&&card.last4)||('#'+id))); } async function hideCard(id, hidden){ const j=await api('/api/cards/'+id+'/hidden',{method:'POST',body:JSON.stringify({hidden:!!hidden})}); if(j.error) return fail('无法更新', j.error); notice(hidden?'已隐藏':'已显示', '#'+id); await loadAll(); render(false); } function skuOptions(pkg, selectedId){ const list=(cache.skus||[]).filter(s=>(!pkg || s.package===pkg) && String(s.note||'').indexOf('作废')<0); if(!list.length) return ''; return list.map(s=>'').join(''); } function skuLabel(s){ if(!s) return ''; return (s.title||s.sku)+' · '+s.sku+(s.product_type?(' · '+s.product_type):''); } function parseJobOffers(j){ const r=jobResult(j); if(Array.isArray(r)) return r; if(r && Array.isArray(r.offers)) return r.offers; if(r && (r.offer_token||r.price||r.sku)) return [r]; return []; } function accountCountry(acc){ const cc=String((acc&&(acc.play_country||acc.country))||'').trim().toUpperCase(); return /^[A-Z]{2}$/.test(cc)?cc:''; } const replacementModes=[ {id:1, name:'按剩余时间折算'}, {id:2, name:'立即补差价'}, {id:3, name:'下次续费改价'}, {id:4, name:'立即全额收费'}, {id:5, name:'到期后切换'}, {id:6, name:'保留现有方案'} ]; function purchaseTokenOf(p){ if(!p) return ''; return p.purchase_token||''; } function accountSubs(aid){ return (cache.subs||[]).filter(s=>s && Number(s.account_id)===Number(aid)); } function replacementModeHtml(selected){ selected=Number(selected||2); return '
'+replacementModes.map(m=>'').join('')+'
'; } async function skuForm(opts){ opts=opts||{}; const upgrade=!!opts.upgrade; const aid=Number(opts.accountId||0); if(!(cache.skus||[]).length || (upgrade && !(cache.subs||[]).some(s=>s && Number(s.account_id)===aid))){ try{ await loadAll(['skus','subs','accounts']); }catch(e){} } const acc=(cache.accounts||[]).find(a=>a && Number(a.id)===aid)||{}; const pkgs=sortApps([...new Set((cache.skus||[]).map(s=>s.package).filter(Boolean))]); const presetPkg=opts.package||''; const presetSku=(cache.skus||[]).find(s=>s.package===presetPkg && s.sku===opts.sku); const subs=accountSubs(aid).filter(subCurrent); const oldOpts=subs.map(s=>'').join(''); const stacked=!!$('#modalRoot .modal-mask'); const root=stacked?$('#modalStack'):$('#modalRoot'); root.innerHTML=''; let picked=null; const pkgEl=$('#buyPkg'), skuEl=$('#buySku'); const paintObid=()=>{ const box=$('#buyObid'); if(!box) return; const spec=obidSpec(pkgEl&&pkgEl.value); if(!spec){ box.innerHTML=''; return; } const remote=spec.mode==='grok'||spec.mode==='claude'; box.innerHTML=''+(spec.profile?'':'')+(remote?'
填写后会立即解析
':''); const input=$('#buyObidInput'); if(input && remote){ let timer=0, seq=0; const run=async()=>{ const raw=input.value.trim(); const out=$('#buyObidResult'); const mine=++seq; if(!raw){ if(out) out.textContent='填写后会立即解析'; return; } if(out) out.textContent='正在解析…'; try{ window._obidAccount=aid; const got=await obidValue(spec.mode, raw); if(mine!==seq) return; if(out){ const row=(k,v)=>'
'+esc(k)+' '+esc(v||'-')+'
'; let html=''; if(got.account) html+=row('obfuscated_id', got.account); if(got.profile) html+=row('profile', got.profile); (got.subscriptions||[]).forEach(s=>{ html+='
'+String(s).split(/ +/).map(part=>{ const i=part.indexOf('='); if(i<0) return esc(part); return ''+esc(part.slice(0,i))+' '+esc(part.slice(i+1)); }).join(' ')+'
'; }); out.innerHTML=html||esc('没有解析到'); } }catch(e){ if(mine===seq && out) out.textContent=e.message||String(e); } }; input.addEventListener('input', ()=>{ clearTimeout(timer); timer=setTimeout(run, 400); }); input.addEventListener('paste', ()=>setTimeout(run, 0)); } }; const refill=()=>{ const pkg=pkgEl?pkgEl.value:''; if(skuEl) skuEl.innerHTML=skuOptions(pkg, skuEl.value); paintObid(); }; if(pkgEl && !upgrade) pkgEl.onchange=()=>{ refill(); picked=null; showLocal(); }; const drawOffers=(list)=>{ const box=$('#buyOffers'); if(!box) return; if(!list.length){ box.innerHTML='
没有报价
'; return; } const rows=list.map((o,i)=>{ const kind=offerKindName(o.offer_kind||o.offer_type); const price=offerPrice(o); const dur=offerDuration(o)||'-'; return ''+esc(kind)+''+esc(price)+''+esc(dur)+''; }).join(''); box.innerHTML=''+rows+'
类型价格时长
'; const choose=i=>{ picked=list[i]||null; box.querySelectorAll('input[name=offerPick]').forEach((el,n)=>{ el.checked=n===i; }); }; choose(0); box.querySelectorAll('tr.pick').forEach(tr=>{ tr.onclick=()=>choose(Number(tr.getAttribute('data-i'))); }); }; const localOffers=sku=>{ const cc=accountCountry(acc); return ((sku&&sku.offers)||[]).filter(o=>{ const got=String(o.country||'').toUpperCase(); return !cc || !got || got===cc || got==='XX'; }); }; const showLocal=()=>{ const sku=(cache.skus||[]).find(s=>Number(s.id)===Number(skuEl&&skuEl.value)); drawOffers(localOffers(sku)); }; if(skuEl) skuEl.onchange=()=>{ picked=null; showLocal(); }; paintObid(); showLocal(); $('#buyQuery').onclick=async()=>{ const sku=(cache.skus||[]).find(s=>Number(s.id)===Number(skuEl&&skuEl.value)); const pkg=(pkgEl&&pkgEl.value)||(sku&&sku.package)||''; const all=(cache.skus||[]).filter(s=>s && s.package===pkg); if(!all.length) return fail('无法查询','这个应用没有 SKU'); modalBusy(true,'刷新报价'); const byType={}; all.forEach(s=>{ const t=s.product_type||'subs'; (byType[t]=byType[t]||[]).push(s.sku); }); let firstErr=''; for(const t of Object.keys(byType)){ const j=await api('/api/sku/details',{method:'POST',body:JSON.stringify({account_id:aid, package:pkg, product_type:t, skus:byType[t], refresh:true})}); if(j.error){ firstErr=j.error; continue; } const done=await waitJob(j.job_id, '查 SKU'); const offers=parseJobOffers(done); const cc=accountCountry(acc)||'XX'; all.forEach(s=>{ if((s.product_type||'subs')!==t) return; const mine=offers.filter(o=>o.sku===s.sku || o.product_id===s.sku).map(o=>Object.assign({}, o, {country:o.country||cc})); if(mine.length) s.offers=mine; }); } modalBusy(false); if(firstErr && !all.some(s=>(s.offers||[]).length)) return fail('无法查询', firstErr); showLocal(); }; const formBody=()=>{ const sku=(cache.skus||[]).find(s=>Number(s.id)===Number(skuEl&&skuEl.value)); if(!sku){ fail('无法购买','请选择 SKU'); return null; } const oldEl=$('#buyOld'); const oldOpt=oldEl&&oldEl.selectedOptions?oldEl.selectedOptions[0]:null; const modeEl=root.querySelector('input[name=replMode]:checked'); return { account_id:aid, package:sku.package, sku:sku.sku, product_type:sku.product_type||'subs', offer_token:(picked&&(picked.offer_token||picked.token))||sku.offer_token||'', upgrade:upgrade, old_purchase_token:upgrade?(opts.oldToken||(oldEl&&oldEl.value)||''):'', old_package:upgrade?((oldOpt&&oldOpt.getAttribute('data-pkg'))||opts.oldPackage||sku.package):'', old_sku:upgrade?((oldOpt&&oldOpt.getAttribute('data-sku'))||opts.oldSku||''):'', old_order_id:upgrade?((oldOpt&&oldOpt.getAttribute('data-order'))||opts.oldOrder||''):'', replacement_mode:upgrade?Number((modeEl&&modeEl.value)||opts.replacementMode||2):0, obid_raw:(($('#buyObidInput')||{}).value||'').trim(), obid_profile:(($('#buyObidProfile')||{}).value||'').trim(), obid_mode:(obidSpec(sku.package)||{}).mode||'', offer:picked }; }; let cancelled=false; let out=null; const done=await new Promise(resolve=>{ $('#mOk').onclick=async()=>{ if(cancelled) return; const draft=formBody(); if(!draft) return; try{ window._obidAccount=draft.account_id||aid; const got=await obidValue(draft.obid_mode, draft.obid_raw); draft.obfuscated_account_id=got.account||''; draft.obfuscated_profile_id=got.profile||draft.obid_profile||''; }catch(e){ fail('无法解析 obid', e.message||String(e)); return; } modalBusy(true, upgrade?'确认升级':'去支付'); const ok=await showPayConfirm(draft); modalBusy(false); if(cancelled) return; if(ok){ out=Object.assign({}, draft, {immediate:!!draft.immediate}); resolve(true); } }; $('#mCancel').onclick=()=>{ cancelled=true; resolve(false); }; bindMaskClose(root, ()=>{ cancelled=true; resolve(false); }); }); root.innerHTML=''; return done?out:null; } async function showPayConfirm(body){ const preview=await api('/api/purchases/preview',{method:'POST',body:JSON.stringify(body)}); if(preview.error && !preview.due && !preview.price) return fail('无法预览', preview.error); const price=preview.price||'-'; const startAt=preview.start||''; const due=preview.due||(startAt?'$0.00':(price||'-')); const rows=[ ['本次应付', due], ['之后价格', price], ['币种', preview.currency||'-'], ['付款开始', startAt||'-'], ['首次扣款', preview.next||'-'] ]; if(preview.detail) rows.push(['说明', preview.detail]); const ok=await modal({ title: body.upgrade?'确认升级':'确认支付', rows: rows, message: preview.error||preview.debug||'', okText: '确认支付', cancelText: '取消', stack: true, extraBefore: '', onOk: ()=>{ body.immediate=!!($('#payNow')&&$('#payNow').checked); } }); return !!ok; } async function buyOne(ev, id, preset){ preset=preset||{}; const body=await skuForm(Object.assign({accountId:id, upgrade:!!preset.upgrade}, preset)); if(!body) return; const payload={ account_id:body.account_id, package:body.package, sku:body.sku, product_type:body.product_type, offer_token:body.offer_token, instrument_id:body.instrument_id||undefined, upgrade:!!body.upgrade, old_purchase_token:body.old_purchase_token||'', old_package:body.old_package||'', old_sku:body.old_sku||'', old_order_id:body.old_order_id||'', replacement_mode:body.replacement_mode||0, immediate:!!body.immediate, obfuscated_account_id:body.obfuscated_account_id||'', obfuscated_profile_id:body.obfuscated_profile_id||'' }; const j=await api('/api/purchases',{method:'POST',body:JSON.stringify(payload)}); if(j.error) return fail('无法购买', j.error); notice(body.upgrade?'正在升级':'正在购买', (body.package||'')+' / '+(body.sku||'')); watchAccountJob(id, 'buy', j.job_id, body.upgrade?'升级':'购买'); refreshList(); } async function buySelected(ev){ const btn=clickBtn(ev); const ids=[...selected]; if(!ids.length) return fail('无法购买','请先勾选账号'); const body=await skuForm({accountId:ids[0], upgrade:false}); if(!body) return; const ok=await modal({title:'批量购买', message:'将对 '+ids.length+' 个账号购买 '+body.package+' / '+body.sku+'。', okText:'确认', cancelText:'取消'}); if(!ok) return; const j=await api('/api/purchases/batch',{method:'POST',body:JSON.stringify({ account_ids:ids, package:body.package, sku:body.sku, product_type:body.product_type, offer_token:body.offer_token, confirm:true })}); if(j.error) return fail('无法购买', j.error); if(j.need_confirm){ const again=await api('/api/purchases/batch',{method:'POST',body:JSON.stringify({ account_ids:ids, package:body.package, sku:body.sku, product_type:body.product_type, offer_token:body.offer_token, confirm:true })}); if(again.error) return fail('无法购买', again.error); await waitJobs(again.job_ids||[], '购买', btn); return; } await waitJobs(j.job_ids||[], '购买', btn); } function sourcePill(src){ const k=String(src||''); if(!k) return '-'; return pill(k); } function renewPill(on){ if(on) return '自动续订'; return '已关闭续订'; }