""" Malaysia Telco Topup & SIM Card Purchase Application Supports cryptocurrency payments (Bitcoin, Ethereum, USDT, etc.) Built with Gradio 6 - Modern UI with themes """ import gradio as gr import random from datetime import datetime from typing import Optional, Dict, Any # Malaysian Telco Providers TELCO_PROVIDERS = { "Maxis": { "plans": ["Hotlink Prepaid", "Maxis Postpaid", "Maxis Fibre"], "min_amount": 5, "max_amount": 500 }, "Celcom": { "plans": ["Celcom Prepaid", "Celcom Postpaid", "Celcom Home Fibre"], "min_amount": 5, "max_amount": 500 }, "Digi": { "plans": ["Digi Prepaid", "Digi Postpaid", "Digi Fibre"], "min_amount": 5, "max_amount": 500 }, "Telekom Malaysia": { "plans": ["Unifi Mobile", "Streamyx", "Unifi Fibre"], "min_amount": 10, "max_amount": 1000 }, "U Mobile": { "plans": ["U Prepaid", "U Postpaid", "U Fibre"], "min_amount": 5, "max_amount": 500 } } # Cryptocurrency Options CRYPTO_OPTIONS = { "Bitcoin (BTC)": {"symbol": "BTC", "network": "Bitcoin"}, "Ethereum (ETH)": {"symbol": "ETH", "network": "Ethereum"}, "USDT (BEP20)": {"symbol": "USDT", "network": "Binance Smart Chain"}, "USDT (ERC20)": {"symbol": "USDT", "network": "Ethereum"}, "BNB": {"symbol": "BNB", "network": "Binance Smart Chain"}, "USDC": {"symbol": "USDC", "network": "Ethereum"} } def validate_phone_number(phone: str) -> bool: """Validate Malaysian phone number format""" if not phone: return False phone = phone.replace(" ", "").replace("-", "") if len(phone) < 10 or len(phone) > 11: return False if phone[0] != '0': return False return True def calculate_crypto_amount(myr_amount: float, crypto_type: str) -> Dict[str, Any]: """Calculate cryptocurrency equivalent amount (simulated rates)""" rates = { "Bitcoin (BTC)": 0.000015, "Ethereum (ETH)": 0.00035, "USDT (BEP20)": 0.22, "USDT (ERC20)": 0.22, "BNB": 0.0035, "USDC": 0.22 } rate = rates.get(crypto_type, 0.22) crypto_amount = myr_amount * rate return { "crypto_amount": crypto_amount, "rate": rate, "symbol": CRYPTO_OPTIONS[crypto_type]["symbol"] } def process_topup( telco: str, plan: str, phone_number: str, amount: float, crypto_type: str, request: Optional[gr.Request] = None ) -> Dict[str, Any]: """Process the topup transaction with cryptocurrency payment""" if not validate_phone_number(phone_number): raise gr.Error("Nombor telefon tidak sah. Sila gunakan format Malaysia (contoh: 0123456789)") if amount < TELCO_PROVIDERS[telco]["min_amount"]: raise gr.Error(f"Amount terlalu rendah. Minimum untuk {telco} ialah RM{TELCO_PROVIDERS[telco]['min_amount']}") if amount > TELCO_PROVIDERS[telco]["max_amount"]: raise gr.Error(f"Amount terlalu tinggi. Maximum untuk {telco} ialah RM{TELCO_PROVIDERS[telco]['max_amount']}") crypto_calc = calculate_crypto_amount(amount, crypto_type) transaction_id = f"TXN{random.randint(100000, 999999)}{datetime.now().strftime('%Y%m%d%H%M%S')}" result = { "status": "success", "transaction_id": transaction_id, "telco": telco, "plan": plan, "phone_number": phone_number, "amount_myr": amount, "crypto_type": crypto_type, "crypto_amount": crypto_calc["crypto_amount"], "crypto_symbol": crypto_calc["symbol"], "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "wallet_address": f"0x{random.randint(1000000000, 9999999999)}...{random.randint(1000, 9999)}" } return result def generate_transaction_summary(result: Dict[str, Any]) -> str: """Generate a formatted transaction summary""" summary = f""" ## â Transaksi Berjaya! **ID Transaksi:** `{result['transaction_id']}` ### đą Butiran Topup - **Telco:** {result['telco']} - **Plan:** {result['plan']} - **Nombor Telefon:** {result['phone_number']} - **Amount (MYR):** RM {result['amount_myr']:.2f} ### đ° Pembayaran Kripto - **Jenis Kripto:** {result['crypto_type']} - **Amount Kripto:** {result['crypto_amount']:.6f} {result['crypto_symbol']} - **Wallet Address:** `{result['wallet_address']}` ### đ Masa Transaksi - **Tarikh:** {result['timestamp']} --- **Status:** â Completed **Reference:** Simpan ID transaksi untuk rujukan masa hadapan. """ return summary def get_available_plans(telco: str) -> list: """Get available plans for selected telco""" if telco in TELCO_PROVIDERS: return TELCO_PROVIDERS[telco]["plans"] return [] def get_amount_range(telco: str) -> tuple: """Get min and max amount for selected telco""" if telco in TELCO_PROVIDERS: return (TELCO_PROVIDERS[telco]["min_amount"], TELCO_PROVIDERS[telco]["max_amount"]) return (5, 500) def create_crypto_payment_info(crypto_type: str, amount: float) -> str: """Create cryptocurrency payment information display""" if not crypto_type or amount <= 0: return "Silakan pilih jenis kripto dan masukkan amount" crypto_calc = calculate_crypto_amount(amount, crypto_type) info = f""" ### đŗ Maklumat Pembayaran **Kripto:** {crypto_type} **Symbol:** {crypto_calc['symbol']} **Network:** {CRYPTO_OPTIONS[crypto_type]['network']} **Amount MYR:** RM {amount:.2f} **Amount Kripto:** {crypto_calc['crypto_amount']:.6f} {crypto_calc['symbol']} **Rate:** 1 MYR = {crypto_calc['rate']} {crypto_calc['symbol']} â ī¸ **Nota:** Rate kripto berubah mengikut pasaran. Amount akhir mungkin berbeza sedikit. """ return info def create_app(): """Create the main Gradio application""" with gr.Blocks() as demo: # Header with branding gr.Markdown(""" # đą Malaysia Telco Topup & SIM Card ### Beli topup internet & SIMkad dengan pembayaran kripto
""", elem_classes=["header-markdown"]) with gr.Tabs(): # Tab 1: Topup Purchase with gr.TabItem("đą Topup Internet", id=1): with gr.Row(): with gr.Column(scale=1): gr.Markdown("### đ Pilih Telco & Plan") telco_dropdown = gr.Dropdown( choices=list(TELCO_PROVIDERS.keys()), label="Pilih Telco", info="Pilih penyedia telekomunikasi", value="Maxis" ) plan_dropdown = gr.Dropdown( choices=get_available_plans("Maxis"), label="Pilih Plan", info="Pilih plan/topup", value="Hotlink Prepaid" ) phone_input = gr.Textbox( label="Nombor Telefon", placeholder="Contoh: 0123456789", info="Masukkan nombor telefon Malaysia", max_length=11 ) amount_slider = gr.Slider( minimum=5, maximum=500, value=30, step=5, label="Amount Topup (MYR)", info="Pilih amount topup" ) with gr.Column(scale=1): gr.Markdown("### đ° Pembayaran Kripto") crypto_dropdown = gr.Dropdown( choices=list(CRYPTO_OPTIONS.keys()), label="Pilih Kripto", info="Pilih cryptocurrency untuk pembayaran", value="USDT (BEP20)" ) crypto_info = gr.Markdown( create_crypto_payment_info("USDT (BEP20)", 30), elem_classes=["crypto-info"] ) submit_btn = gr.Button( "â Beli Sekarang", variant="primary", size="lg" ) clear_btn = gr.Button( "đ Reset", variant="secondary" ) with gr.Accordion("đ Hasil Transaksi", open=False): transaction_result = gr.Markdown( label="Transaction Summary", elem_classes=["transaction-result"] ) def update_plans(telco): plans = get_available_plans(telco) min_amt, max_amt = get_amount_range(telco) return gr.Dropdown( choices=plans, value=plans[0] if plans else None ), gr.Slider(minimum=min_amt, maximum=max_amt) telco_dropdown.change( fn=update_plans, inputs=[telco_dropdown], outputs=[plan_dropdown, amount_slider] ) def update_crypto_info(crypto_type, amount): return create_crypto_payment_info(crypto_type, amount) crypto_dropdown.change( fn=update_crypto_info, inputs=[crypto_dropdown, amount_slider], outputs=[crypto_info] ) amount_slider.change( fn=update_crypto_info, inputs=[crypto_dropdown, amount_slider], outputs=[crypto_info] ) def process_transaction(telco, plan, phone, amount, crypto): try: result = process_topup(telco, plan, phone, amount, crypto) summary = generate_transaction_summary(result) gr.Success(f"â Transaksi berjaya! ID: {result['transaction_id']}") return summary except gr.Error as e: gr.Error(str(e)) return f"â **Error:** {str(e)}" submit_btn.click( fn=process_transaction, inputs=[telco_dropdown, plan_dropdown, phone_input, amount_slider, crypto_dropdown], outputs=[transaction_result], api_visibility="public" ) clear_btn.click( fn=lambda: ( "Maxis", "Hotlink Prepaid", "", 30, "USDT (BEP20)", create_crypto_payment_info("USDT (BEP20)", 30) ), inputs=None, outputs=[telco_dropdown, plan_dropdown, phone_input, amount_slider, crypto_dropdown, crypto_info], api_visibility="undocumented" ) # Tab 2: SIM Card Purchase with gr.TabItem("đ SIM Card Baru", id=2): gr.Markdown(""" ### đ Pilih SIM Card Package Pilih package SIM card baru dari telco kegemaran anda. Pembayaran mudah dengan cryptocurrency! """) with gr.Row(): with gr.Column(): sim_telco = gr.Dropdown( choices=list(TELCO_PROVIDERS.keys()), label="Pilih Telco", value="Maxis" ) sim_plan = gr.Dropdown( choices=["SIM Only Prepaid", "SIM Only Postpaid", "SIM + Device"], label="Pilih Package", value="SIM Only Prepaid" ) sim_name = gr.Textbox( label="Nama Penuh", placeholder="Nama seperti dalam kad pengenalan", info="Nama untuk pendaftaran SIM" ) sim_ic = gr.Textbox( label="Nombor Kad Pengenalan", placeholder="Contoh: 900101-14-5678", info="No. IC untuk pendaftaran" ) sim_delivery = gr.Radio( choices=["Pos Laju", "Pickup Store", "Delivery Same Day"], label="Kaedah Delivery", value="Pos Laju" ) with gr.Column(): sim_crypto = gr.Dropdown( choices=list(CRYPTO_OPTIONS.keys()), label="Pilih Kripto", value="USDT (BEP20)" ) sim_price = gr.Number( label="Harga SIM (MYR)", value=50, minimum=10, maximum=500 ) sim_info = gr.Markdown( "**đ° Info Pembayaran:**\n\nPembayaran akan dikira berdasarkan harga SIM + crypto rate semasa." ) sim_submit = gr.Button("đ Order SIM Card", variant="primary") sim_result = gr.Markdown(label="Order Summary") def process_sim_order(telco, plan, name, ic, delivery, crypto, price): if not name or not ic: gr.Error("Sila masukkan nama dan nombor IC") return "â **Error:** Maklumat tidak lengkap" transaction_id = f"SIM{random.randint(100000, 999999)}{datetime.now().strftime('%Y%m%d%H%M%S')}" crypto_calc = calculate_crypto_amount(price, crypto) summary = f""" ## â Order SIM Card Berjaya! **ID Order:** `{transaction_id}` ### đ Butiran SIM Card - **Telco:** {telco} - **Package:** {plan} - **Nama:** {name} - **No. IC:** {ic} - **Delivery:** {delivery} - **Harga (MYR):** RM {price:.2f} ### đ° Pembayaran Kripto - **Kripto:** {crypto} - **Amount:** {crypto_calc['crypto_amount']:.6f} {crypto_calc['symbol']} **Status:** â Processing **Estimate Delivery:** 2-3 hari bekerja """ gr.Success(f"â Order SIM berjaya! ID: {transaction_id}") return summary sim_submit.click( fn=process_sim_order, inputs=[sim_telco, sim_plan, sim_name, sim_ic, sim_delivery, sim_crypto, sim_price], outputs=[sim_result], api_visibility="public" ) # Tab 3: Transaction History with gr.TabItem("đ History Transaksi", id=3): gr.Markdown(""" ### đ Lihat History Transaksi Semua transaksi topup dan SIM card akan disimpan di sini. """) history_table = gr.Dataframe( headers=["ID", "Telco", "Type", "Amount (MYR)", "Crypto", "Status", "Date"], datatype=["str", "str", "str", "number", "str", "str", "str"], label="Transaction History", interactive=False ) sample_history = [ ["TXN123456", "Maxis", "Topup", 30.00, "USDT", "Completed", "2024-01-15"], ["TXN123457", "Celcom", "Topup", 50.00, "BTC", "Completed", "2024-01-14"], ["SIM987654", "Digi", "SIM Card", 50.00, "ETH", "Processing", "2024-01-13"], ] history_table.value = sample_history gr.Markdown(""" **đĄ Tips:** - Simpan ID transaksi untuk rujukan - Contact support jika ada masalah - Check status transaksi dalam 24 jam """) gr.Markdown(""" --- ### âšī¸ Maklumat Tambahan **Supported Telcos:** Maxis, Celcom, Digi, Telekom Malaysia, U Mobile **Supported Crypto:** Bitcoin, Ethereum, USDT (BEP20/ERC20), BNB, USDC **Processing Time:** Instant untuk topup, 2-3 hari untuk SIM card **â ī¸ Disclaimer:** Aplikasi ini adalah demo. Untuk penggunaan sebenar, sila integrate dengan payment gateway yang sah. """, elem_classes=["footer-markdown"]) return demo if __name__ == "__main__": demo = create_app() demo.launch( theme=gr.themes.Soft( primary_hue="blue", secondary_hue="indigo", neutral_hue="slate", font=gr.themes.GoogleFont("Inter"), ).set( button_primary_background_fill="*primary_600", button_primary_background_fill_hover="*primary_700", block_title_text_weight="600", ), footer_links=[ {"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}, {"label": "Gradio Docs", "url": "https://gradio.app/docs"}, ], css=""" .header-markdown { text-align: center; margin-bottom: 20px; } .crypto-info { background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); border-radius: 12px; padding: 15px; border: 1px solid #bde0fe; } .transaction-result { background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); border-radius: 12px; padding: 15px; border: 1px solid #fcd34d; } .footer-markdown { text-align: center; margin-top: 30px; opacity: 0.8; } """, js=""" function() { console.log('Malaysia Telco Topup App loaded successfully!'); } """, )