TakoGift (qris only)

JavaScriptPublic
by zx-apiAug 9, 2026, 06:58 AMExpires: Never274 views
TakoGift (qris only)
Raw
1class TakoGift {
2  constructor(username) {
3    this.username = username;
4    this.baseUrl = 'https://tako.id';
5    
6    this.deploymentId = 'a5010607774e245ac792354dee72391b1c02d7b3';
7    this.serverActionId = '8b17364244d040d72da4c5f426ac6eea8658b6b9';
8    
9    this.browserHeaders = {
10      'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
11      'Origin': 'https://tako.id',
12      'Referer': `https://tako.id/${this.username}/gift`
13    };
14  }
15
16  async createGift(amount, email = 'anonymous@example.com', message = 'Support!') {
17    const url = `${this.baseUrl}/api/v1/gift/${this.username}`;
18    
19    const payload = {
20      name: 'Anonymous',
21      email: email,
22      hideEmail: true,
23      paymentMethod: 'qris',
24      currency: 'idr',
25      amount: amount,
26      message: message,
27      usePriority: false
28    };
29
30    const response = await fetch(url, {
31      method: 'POST',
32      headers: {
33        'Content-Type': 'application/json',
34        'Accept': 'application/json',
35        ...this.browserHeaders
36      },
37      body: JSON.stringify(payload)
38    });
39
40    const rawText = await response.text();
41
42    if (rawText.trim().startsWith('<!DOCTYPE') || rawText.trim().startsWith('<html')) {
43      throw new Error(`❌ Server mengembalikan HTML (Status: ${response.status}). Kemungkinan IP diblokir Cloudflare atau WAF.\nSnippet: ${rawText.substring(0, 300)}...`);
44    }
45
46    let data;
47    try {
48      data = JSON.parse(rawText);
49    } catch (e) {
50      throw new Error(`❌ Gagal parse JSON (Status: ${response.status}). Raw: ${rawText.substring(0, 200)}`);
51    }
52    
53    if (data.statusCode === 206 && data.result.success) {
54      return data.result.transactionId;
55    }
56    
57    throw new Error(`❌ Gagal membuat gift: ${JSON.stringify(data)}`);
58  }
59
60  async getPaymentDetails(transactionId) {
61    const url = `${this.baseUrl}/pay/${transactionId}`;
62    const body = JSON.stringify([transactionId]);
63
64    const response = await fetch(url, {
65      method: 'POST',
66      headers: {
67        'Accept': 'text/x-component',
68        'Next-Action': this.serverActionId,
69        'Content-Type': 'text/plain;charset=UTF-8',
70        'x-deployment-id': this.deploymentId,
71        'Next-Url': `/${this.username}`,
72        ...this.browserHeaders,
73        'Referer': `https://tako.id/pay/${transactionId}`
74      },
75      body: body
76    });
77
78    const text = await response.text();
79
80    if (text.trim().startsWith('<!DOCTYPE') || text.trim().startsWith('<html')) {
81      throw new Error(`❌ Server mengembalikan HTML saat mengambil detail pembayaran.\nSnippet: ${text.substring(0, 300)}...`);
82    }
83
84    return this.parseRSCResponse(text);
85  }
86
87  async checkStatus(transactionId) {
88    return await this.getPaymentDetails(transactionId);
89  }
90
91  parseRSCResponse(text) {
92    const lines = text.split('\n');
93    for (const line of lines) {
94      const match = line.match(/^\d+:(\{.*\})$/);
95      if (match) {
96        try {
97          const data = JSON.parse(match[1]);
98          if (data.status || data.qrData) {
99            return data;
100          }
101        } catch (e) {
102        }
103      }
104    }
105    throw new Error('❌ Gagal parse RSC response dari server');
106  }
107}
108
109async function main() {
110  const scraper = new TakoGift('cmnty'); // Ganti dengan username kreator target / bisa pake username kalian
111  
112  try {
113    const amount = 10000; // Nominal Rp 10.000
114    console.log(`[1/3] Membuat gift sebesar Rp ${amount.toLocaleString('id-ID')}...`);
115    const transactionId = await scraper.createGift(amount);
116    console.log(`✅ Transaksi berhasil dibuat. ID: ${transactionId}\n`);
117
118    console.log('[2/3] Mengambil detail pembayaran (QRIS)...');
119    const paymentDetails = await scraper.getPaymentDetails(transactionId);
120    console.log('Status Awal  :', paymentDetails.status);
121    console.log('Provider     :', paymentDetails.provider);
122    console.log('QRIS String  :', paymentDetails.qrData); 
123    console.log('Amount       :', paymentDetails.amount, '\n');
124
125    console.log('[3/3] Mengecek status transaksi...');
126    const statusCheck = await scraper.checkStatus(transactionId);
127    console.log('✅ Status Terkini:', statusCheck.status);
128    
129  } catch (error) {
130    console.error(error.message);
131  }
132}
133
134main();
135
136[1/3] Membuat gift sebesar Rp 10.000...Transaksi berhasil dibuat. ID: d87aac3b-5726-45c5-aca9-e98cbee08a86                                                
137[2/3] Mengambil detail pembayaran (QRIS)...
138Status Awal  : pending
139Provider     : xendit
140QRIS String  : 00020101021226650013CO.XENDIT.WWW011893600848000000468002158d3HVwJVVFvk5Y90303UME51370014ID.CO.QRIS.WWW0215ID20254096788985204509953033605405100005802ID5925Tako (PT Hobimu Jadi Cuan6015JAKARTA SELATAN61051221062290525kGHTgZVjhSQUpR3zKoVNgxuMo6304D471
141Amount       : 10000
142
143[3/3] Mengecek status transaksi...
144Status Terkini: pending
144 lines·4,891 chars·4.8 KB