safepoint Detail transaksi
This commit is contained in:
		
							parent
							
								
									d4245c5906
								
							
						
					
					
						commit
						c56cae64b9
					
				@ -140,84 +140,85 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
            String tid = intent.getStringExtra("tid");
 | 
					            String tid = intent.getStringExtra("tid");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Log received data for debugging
 | 
					            // Log received data for debugging
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 RECEIVED DATA:");
 | 
				
			||||||
            Log.d("ReceiptActivity", "   amount: " + amount);
 | 
					            Log.d("ReceiptActivity", "   amount: " + amount);
 | 
				
			||||||
            Log.d("ReceiptActivity", "grossAmount: " + grossAmount);
 | 
					 | 
				
			||||||
            Log.d("ReceiptActivity", "merchantName: " + merchantNameStr);
 | 
					 | 
				
			||||||
            Log.d("ReceiptActivity", "   referenceId: " + referenceId);
 | 
					            Log.d("ReceiptActivity", "   referenceId: " + referenceId);
 | 
				
			||||||
            Log.d("ReceiptActivity", "createdAt: " + createdAt);
 | 
					            Log.d("ReceiptActivity", "   orderId: " + orderId);
 | 
				
			||||||
            Log.d("ReceiptActivity", "   channelCode: " + channelCode);
 | 
					            Log.d("ReceiptActivity", "   channelCode: " + channelCode);
 | 
				
			||||||
            Log.d("ReceiptActivity", "acquirer: " + acquirer);
 | 
					            Log.d("ReceiptActivity", "   acquirer (from intent): " + acquirer);
 | 
				
			||||||
            Log.d("ReceiptActivity", "mid: " + mid);
 | 
					            Log.d("ReceiptActivity", "   createdAt: " + createdAt);
 | 
				
			||||||
            Log.d("ReceiptActivity", "tid: " + tid);
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 1. Set merchant data with defaults
 | 
					            // 1. Set merchant data with defaults
 | 
				
			||||||
            merchantName.setText(merchantNameStr != null ? merchantNameStr : "Marcel Panjaitan");
 | 
					            merchantName.setText(merchantNameStr != null ? merchantNameStr : "Marcel Panjaitan");
 | 
				
			||||||
            merchantLocation.setText(merchantLocationStr != null ? merchantLocationStr : "Jakarta, Indonesia");
 | 
					            merchantLocation.setText(merchantLocationStr != null ? merchantLocationStr : "Jakarta, Indonesia");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 2. Set MID and TID - prioritize from intent, then defaults
 | 
					            // 2. Set MID and TID
 | 
				
			||||||
            midText.setText(mid != null ? mid : "71000026521");
 | 
					            midText.setText(mid != null ? mid : "71000026521");
 | 
				
			||||||
            tidText.setText(tid != null ? tid : "73001500");
 | 
					            tidText.setText(tid != null ? tid : "73001500");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 3. Set transaction number - prioritize reference_id
 | 
					            // 3. Set transaction number
 | 
				
			||||||
            String displayTransactionNumber = null;
 | 
					            String displayTransactionNumber = null;
 | 
				
			||||||
            if (referenceId != null && !referenceId.isEmpty()) {
 | 
					            if (referenceId != null && !referenceId.isEmpty()) {
 | 
				
			||||||
                displayTransactionNumber = referenceId;
 | 
					                displayTransactionNumber = referenceId;
 | 
				
			||||||
                Log.d("ReceiptActivity", "Using reference_id as transaction number: " + referenceId);
 | 
					 | 
				
			||||||
            } else if (transactionId != null && !transactionId.isEmpty()) {
 | 
					            } else if (transactionId != null && !transactionId.isEmpty()) {
 | 
				
			||||||
                displayTransactionNumber = transactionId;
 | 
					                displayTransactionNumber = transactionId;
 | 
				
			||||||
                Log.d("ReceiptActivity", "Using transaction_id as transaction number: " + transactionId);
 | 
					 | 
				
			||||||
            } else if (orderId != null && !orderId.isEmpty()) {
 | 
					            } else if (orderId != null && !orderId.isEmpty()) {
 | 
				
			||||||
                displayTransactionNumber = orderId;
 | 
					                displayTransactionNumber = orderId;
 | 
				
			||||||
                Log.d("ReceiptActivity", "Using order_id as transaction number: " + orderId);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            transactionNumber.setText(displayTransactionNumber != null ? displayTransactionNumber : "N/A");
 | 
					            transactionNumber.setText(displayTransactionNumber != null ? displayTransactionNumber : "N/A");
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 4. Set transaction date - prioritize createdAt, format as dd/MM/yyyy HH:mm
 | 
					            // 4. Set transaction date
 | 
				
			||||||
            String displayDate = null;
 | 
					            String displayDate = null;
 | 
				
			||||||
            if (createdAt != null && !createdAt.isEmpty()) {
 | 
					            if (createdAt != null && !createdAt.isEmpty()) {
 | 
				
			||||||
                displayDate = formatDateFromCreatedAt(createdAt);
 | 
					                displayDate = formatDateFromCreatedAt(createdAt);
 | 
				
			||||||
                Log.d("ReceiptActivity", "Formatted createdAt: " + createdAt + " -> " + displayDate);
 | 
					 | 
				
			||||||
            } else if (transactionDateStr != null && !transactionDateStr.isEmpty()) {
 | 
					            } else if (transactionDateStr != null && !transactionDateStr.isEmpty()) {
 | 
				
			||||||
                displayDate = transactionDateStr;
 | 
					                displayDate = transactionDateStr;
 | 
				
			||||||
                Log.d("ReceiptActivity", "Using provided transaction_date: " + transactionDateStr);
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                displayDate = getCurrentDateTime();
 | 
					                displayDate = getCurrentDateTime();
 | 
				
			||||||
                Log.d("ReceiptActivity", "Using current datetime: " + displayDate);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            transactionDate.setText(displayDate);
 | 
					            transactionDate.setText(displayDate);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 5. Set payment method - use channel_code mapping
 | 
					            // 5. Set payment method
 | 
				
			||||||
            String displayPaymentMethod = getPaymentMethodFromChannelCode(channelCode, paymentMethodStr);
 | 
					            String displayPaymentMethod = getPaymentMethodFromChannelCode(channelCode, paymentMethodStr);
 | 
				
			||||||
            paymentMethod.setText(displayPaymentMethod);
 | 
					            paymentMethod.setText(displayPaymentMethod);
 | 
				
			||||||
            Log.d("ReceiptActivity", "Payment method: " + displayPaymentMethod + " (from channel: " + channelCode + ")");
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 6. Set card type - use acquirer with comprehensive mapping
 | 
					            // 6. ✅ IMPROVED: Enhanced card type detection for QRIS
 | 
				
			||||||
            // For QRIS, we need to get the actual acquirer (GoPay, OVO, DANA, etc.)
 | 
					            String displayCardType = null;
 | 
				
			||||||
            String displayCardType = getCardTypeFromAcquirer(acquirer, channelCode, cardTypeStr);
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Special handling for QRIS - if we only have "QRIS" or "qris", try to get real acquirer
 | 
					            if (channelCode != null && channelCode.equalsIgnoreCase("QRIS")) {
 | 
				
			||||||
            if (displayCardType.equalsIgnoreCase("QRIS") && channelCode != null && channelCode.equalsIgnoreCase("QRIS")) {
 | 
					                Log.d("ReceiptActivity", "🔍 QRIS transaction detected - searching for real acquirer");
 | 
				
			||||||
                // For QRIS transactions, we should try to determine the actual acquirer
 | 
					                
 | 
				
			||||||
                // This might require additional API call or webhook data parsing
 | 
					                // For QRIS, try to get real acquirer from webhook data
 | 
				
			||||||
                Log.w("ReceiptActivity", "QRIS transaction detected but no specific acquirer found. Using default.");
 | 
					                if (referenceId != null && !referenceId.isEmpty()) {
 | 
				
			||||||
                // In production, this should fetch the real acquirer from transaction status API
 | 
					                    String realAcquirer = fetchRealAcquirerSync(referenceId);
 | 
				
			||||||
                displayCardType = acquirer != null && !acquirer.equalsIgnoreCase("qris") ? 
 | 
					                    if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
                    getCardTypeFromAcquirer(acquirer, channelCode, cardTypeStr) : "GoPay"; // Default QRIS acquirer
 | 
					                        displayCardType = getCardTypeFromAcquirer(realAcquirer, null, null);
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "✅ QRIS real acquirer found: " + realAcquirer + " -> " + displayCardType);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        Log.w("ReceiptActivity", "⚠️ QRIS real acquirer not found, using generic QRIS");
 | 
				
			||||||
 | 
					                        displayCardType = "QRIS";
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        // Start async search for better results
 | 
				
			||||||
 | 
					                        fetchRealAcquirerFromWebhook(referenceId);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    displayCardType = "QRIS";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // Non-QRIS transaction
 | 
				
			||||||
 | 
					                displayCardType = getCardTypeFromAcquirer(acquirer, channelCode, cardTypeStr);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            cardType.setText(displayCardType);
 | 
					            cardType.setText(displayCardType);
 | 
				
			||||||
            Log.d("ReceiptActivity", "Card type: " + displayCardType + " (from acquirer: " + acquirer + ")");
 | 
					            Log.d("ReceiptActivity", "💳 FINAL CARD TYPE: " + displayCardType);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // 7. Format and set amounts - prioritize amount over grossAmount
 | 
					            // 7. Format and set amounts
 | 
				
			||||||
            setAmountData(amount, grossAmount);
 | 
					            setAmountData(amount, grossAmount);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            Log.d("ReceiptActivity", "=== TRANSACTION DATA LOADED ===");
 | 
					            Log.d("ReceiptActivity", "=== TRANSACTION DATA LOADED ===");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Format date from createdAt field (yyyy-MM-dd HH:mm:ss) to Indonesian format (dd/MM/yyyy HH:mm)
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private String formatDateFromCreatedAt(String createdAt) {
 | 
					    private String formatDateFromCreatedAt(String createdAt) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            // Input format from database: "yyyy-MM-dd HH:mm:ss"
 | 
					            // Input format from database: "yyyy-MM-dd HH:mm:ss"
 | 
				
			||||||
@ -291,83 +292,135 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
    private String getCardTypeFromAcquirer(String acquirer, String channelCode, String fallbackCardType) {
 | 
					    private String getCardTypeFromAcquirer(String acquirer, String channelCode, String fallbackCardType) {
 | 
				
			||||||
        // STEP 1: If we have a valid acquirer that's not generic "qris", use it
 | 
					        // STEP 1: If we have a valid acquirer that's not generic "qris", use it
 | 
				
			||||||
        if (acquirer != null && !acquirer.isEmpty() && !acquirer.equalsIgnoreCase("qris")) {
 | 
					        if (acquirer != null && !acquirer.isEmpty() && !acquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
            String acq = acquirer.toLowerCase();
 | 
					            String acq = acquirer.toLowerCase().trim();
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Comprehensive acquirer mapping based on Midtrans
 | 
					            Log.d("ReceiptActivity", "🔍 Mapping acquirer: '" + acquirer + "' -> '" + acq + "'");
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // ✅ COMPREHENSIVE acquirer mapping (case-insensitive)
 | 
				
			||||||
            switch (acq) {
 | 
					            switch (acq) {
 | 
				
			||||||
                // E-Wallet acquirers
 | 
					                // E-Wallet acquirers (most common for QRIS)
 | 
				
			||||||
                case "gopay": return "GoPay";
 | 
					                case "gopay": 
 | 
				
			||||||
                case "shopeepay": return "ShopeePay"; 
 | 
					                case "go-pay": 
 | 
				
			||||||
 | 
					                case "gojek": return "GoPay";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "shopeepay": 
 | 
				
			||||||
 | 
					                case "shopee_pay": 
 | 
				
			||||||
 | 
					                case "shopee": return "ShopeePay";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "ovo": return "OVO";
 | 
					                case "ovo": return "OVO";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "dana": return "DANA";
 | 
					                case "dana": return "DANA";
 | 
				
			||||||
                case "linkaja": return "LinkAja";
 | 
					                
 | 
				
			||||||
                case "jenius": return "Jenius";
 | 
					                case "linkaja": 
 | 
				
			||||||
                case "kaspro": return "KasPro";
 | 
					                case "link_aja": 
 | 
				
			||||||
 | 
					                case "tcash": return "LinkAja";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "jenius": 
 | 
				
			||||||
 | 
					                case "btpn": return "Jenius";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "kaspro": 
 | 
				
			||||||
 | 
					                case "kas_pro": return "KasPro";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "sakuku": 
 | 
				
			||||||
 | 
					                case "saku_ku": return "SakuKu";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "doku": 
 | 
				
			||||||
 | 
					                case "doku_wallet": return "DOKU";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "paymi": 
 | 
				
			||||||
 | 
					                case "pay_mi": return "PayMi";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "isaku": 
 | 
				
			||||||
 | 
					                case "i_saku": return "i.Saku";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // Bank acquirers
 | 
					                // Bank acquirers
 | 
				
			||||||
                case "bca": return "BCA";
 | 
					                case "bca": 
 | 
				
			||||||
 | 
					                case "bank_bca": return "BCA";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "mandiri":
 | 
					                case "mandiri":
 | 
				
			||||||
 | 
					                case "bank_mandiri":
 | 
				
			||||||
                case "mandiri_bill": return "Mandiri";
 | 
					                case "mandiri_bill": return "Mandiri";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "bni":
 | 
					                case "bni":
 | 
				
			||||||
 | 
					                case "bank_bni":
 | 
				
			||||||
                case "bni_va": return "BNI";
 | 
					                case "bni_va": return "BNI";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "bri":
 | 
					                case "bri":
 | 
				
			||||||
 | 
					                case "bank_bri":
 | 
				
			||||||
                case "bri_va": return "BRI";
 | 
					                case "bri_va": return "BRI";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "permata":
 | 
					                case "permata":
 | 
				
			||||||
 | 
					                case "bank_permata":
 | 
				
			||||||
                case "permata_va": return "Permata";
 | 
					                case "permata_va": return "Permata";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "cimb":
 | 
					                case "cimb":
 | 
				
			||||||
 | 
					                case "cimb_niaga":
 | 
				
			||||||
 | 
					                case "bank_cimb":
 | 
				
			||||||
                case "cimb_va": return "CIMB Niaga";
 | 
					                case "cimb_va": return "CIMB Niaga";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "danamon":
 | 
					                case "danamon":
 | 
				
			||||||
 | 
					                case "bank_danamon":
 | 
				
			||||||
                case "danamon_va": return "Danamon";
 | 
					                case "danamon_va": return "Danamon";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                case "bsi":
 | 
					                case "bsi":
 | 
				
			||||||
                case "bsi_va": return "BSI";
 | 
					                case "bank_bsi":
 | 
				
			||||||
                case "maybank": return "Maybank";
 | 
					                case "bsi_va": 
 | 
				
			||||||
 | 
					                case "syariah_indonesia": return "BSI";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "maybank":
 | 
				
			||||||
 | 
					                case "bank_maybank": return "Maybank";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "bca_digital":
 | 
				
			||||||
 | 
					                case "blu": return "BCA Digital";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "jago":
 | 
				
			||||||
 | 
					                case "bank_jago": return "Bank Jago";
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case "seabank":
 | 
				
			||||||
 | 
					                case "sea_bank": return "SeaBank";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // Credit card acquirers
 | 
					                // Credit card acquirers
 | 
				
			||||||
                case "visa": return "Visa";
 | 
					                case "visa": return "Visa";
 | 
				
			||||||
                case "mastercard": return "Mastercard";
 | 
					                case "mastercard": 
 | 
				
			||||||
 | 
					                case "master_card": return "Mastercard";
 | 
				
			||||||
                case "jcb": return "JCB";
 | 
					                case "jcb": return "JCB";
 | 
				
			||||||
                case "amex":
 | 
					                case "amex":
 | 
				
			||||||
                case "american_express": return "American Express";
 | 
					                case "american_express": return "American Express";
 | 
				
			||||||
 | 
					                case "discover": return "Discover";
 | 
				
			||||||
 | 
					                case "unionpay":
 | 
				
			||||||
 | 
					                case "union_pay": return "UnionPay";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // Over-the-counter
 | 
					                // Over-the-counter
 | 
				
			||||||
                case "alfamart": return "Alfamart";
 | 
					                case "alfamart": 
 | 
				
			||||||
                case "indomaret": return "Indomaret";
 | 
					                case "alfa_mart": return "Alfamart";
 | 
				
			||||||
 | 
					                case "indomaret": 
 | 
				
			||||||
 | 
					                case "indo_maret": return "Indomaret";
 | 
				
			||||||
 | 
					                case "pos_indonesia": return "Pos Indonesia";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                // Buy now pay later
 | 
					                // Buy now pay later
 | 
				
			||||||
                case "akulaku": return "Akulaku";
 | 
					                case "akulaku": return "Akulaku";
 | 
				
			||||||
                case "kredivo": return "Kredivo";
 | 
					                case "kredivo": return "Kredivo";
 | 
				
			||||||
                case "indodana": return "Indodana";
 | 
					                case "indodana": 
 | 
				
			||||||
 | 
					                case "indo_dana": return "Indodana";
 | 
				
			||||||
 | 
					                case "traveloka_paylater": 
 | 
				
			||||||
 | 
					                case "traveloka": return "Traveloka PayLater";
 | 
				
			||||||
 | 
					                case "atome": return "Atome";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
                    // Return capitalized version of acquirer if not in mapping
 | 
					                    // Return capitalized version of acquirer if not in mapping
 | 
				
			||||||
                    return capitalizeFirstLetter(acquirer);
 | 
					                    String capitalized = capitalizeFirstLetter(acquirer);
 | 
				
			||||||
 | 
					                    Log.d("ReceiptActivity", "🔤 Using capitalized acquirer: " + capitalized);
 | 
				
			||||||
 | 
					                    return capitalized;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // STEP 2: For QRIS transactions, try to fetch real acquirer from webhook data
 | 
					        // STEP 2: Fallback based on channel code
 | 
				
			||||||
        if (channelCode != null && channelCode.equalsIgnoreCase("QRIS")) {
 | 
					 | 
				
			||||||
            String referenceId = getIntent().getStringExtra("reference_id");
 | 
					 | 
				
			||||||
            if (referenceId != null && !referenceId.isEmpty()) {
 | 
					 | 
				
			||||||
                Log.d("ReceiptActivity", "🔍 QRIS detected, fetching real acquirer for: " + referenceId);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                // Try to get real acquirer from webhook data synchronously for initial load
 | 
					 | 
				
			||||||
                String realAcquirer = fetchRealAcquirerSync(referenceId);
 | 
					 | 
				
			||||||
                if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
 | 
					 | 
				
			||||||
                    Log.d("ReceiptActivity", "✅ Found real acquirer synchronously: " + realAcquirer);
 | 
					 | 
				
			||||||
                    return getCardTypeFromAcquirer(realAcquirer, null, null);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                // If sync fetch failed, try async and show generic QRIS for now
 | 
					 | 
				
			||||||
                fetchRealAcquirerFromWebhook(referenceId);
 | 
					 | 
				
			||||||
                return "QRIS"; // ✅ FIXED: Show QRIS instead of defaulting to GoPay
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // STEP 3: Fallback based on channel code
 | 
					 | 
				
			||||||
        if (channelCode != null && !channelCode.isEmpty()) {
 | 
					        if (channelCode != null && !channelCode.isEmpty()) {
 | 
				
			||||||
            String code = channelCode.toUpperCase();
 | 
					            String code = channelCode.toUpperCase();
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 Using channel code fallback: " + code);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            switch (code) {
 | 
					            switch (code) {
 | 
				
			||||||
                case "QRIS": return "QRIS"; // ✅ FIXED: Generic QRIS instead of GoPay
 | 
					                case "QRIS": return "QRIS"; // Generic QRIS
 | 
				
			||||||
                case "DEBIT": return "Debit";
 | 
					                case "DEBIT": return "Debit";
 | 
				
			||||||
                case "CREDIT": return "Credit";
 | 
					                case "CREDIT": return "Credit";
 | 
				
			||||||
                case "BCA": return "BCA";
 | 
					                case "BCA": return "BCA";
 | 
				
			||||||
@ -378,23 +431,26 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // STEP 4: Final fallback
 | 
					        // STEP 3: Final fallback
 | 
				
			||||||
        return fallbackCardType != null ? fallbackCardType : "Unknown"; // ✅ FIXED: Unknown instead of GoPay
 | 
					        String result = fallbackCardType != null ? fallbackCardType : "Unknown";
 | 
				
			||||||
 | 
					        Log.d("ReceiptActivity", "🔍 Using final fallback: " + result);
 | 
				
			||||||
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    private String fetchRealAcquirerSync(String referenceId) {
 | 
					    private String fetchRealAcquirerSync(String referenceId) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Log.d("ReceiptActivity", "🔍 Sync search for acquirer: " + referenceId);
 | 
					            Log.d("ReceiptActivity", "🔍 Sync search for acquirer: " + referenceId);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            String queryUrl = "https://be-edc.msvc.app/api-logs?limit=50&sortOrder=DESC&sortColumn=created_at";
 | 
					            // ✅ IMPROVED: Search with broader scope for better matches
 | 
				
			||||||
 | 
					            String queryUrl = "https://be-edc.msvc.app/api-logs?limit=100&sortOrder=DESC&sortColumn=created_at";
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            URL url = new URL(queryUrl);
 | 
					            URL url = new URL(queryUrl);
 | 
				
			||||||
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | 
					            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | 
				
			||||||
            conn.setRequestMethod("GET");
 | 
					            conn.setRequestMethod("GET");
 | 
				
			||||||
            conn.setRequestProperty("Accept", "application/json");
 | 
					            conn.setRequestProperty("Accept", "application/json");
 | 
				
			||||||
            conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
 | 
					            conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
 | 
				
			||||||
            conn.setConnectTimeout(5000); // Short timeout for sync call
 | 
					            conn.setConnectTimeout(8000); // Slightly longer timeout for better results
 | 
				
			||||||
            conn.setReadTimeout(5000);
 | 
					            conn.setReadTimeout(8000);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (conn.getResponseCode() == 200) {
 | 
					            if (conn.getResponseCode() == 200) {
 | 
				
			||||||
                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 | 
					                BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 | 
				
			||||||
@ -408,54 +464,27 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
                org.json.JSONArray results = json.optJSONArray("results");
 | 
					                org.json.JSONArray results = json.optJSONArray("results");
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (results != null && results.length() > 0) {
 | 
					                if (results != null && results.length() > 0) {
 | 
				
			||||||
                    // Search for the most recent settlement/success transaction
 | 
					                    Log.d("ReceiptActivity", "📊 Sync analyzing " + results.length() + " webhook logs");
 | 
				
			||||||
                    for (int i = 0; i < results.length(); i++) {
 | 
					 | 
				
			||||||
                        org.json.JSONObject log = results.getJSONObject(i);
 | 
					 | 
				
			||||||
                        org.json.JSONObject reqBody = log.optJSONObject("request_body");
 | 
					 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                        if (reqBody != null) {
 | 
					                    // ✅ PRIORITY SEARCH: Look for settlement first, then pending, then any
 | 
				
			||||||
                            String logReferenceId = reqBody.optString("reference_id", "");
 | 
					                    String[] searchPriority = {"settlement", "capture", "success", "pending", ""};
 | 
				
			||||||
                            String logTransactionStatus = reqBody.optString("transaction_status", "");
 | 
					 | 
				
			||||||
                            String logAcquirer = reqBody.optString("acquirer", "");
 | 
					 | 
				
			||||||
                            String logIssuer = reqBody.optString("issuer", "");
 | 
					 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                            // Check for direct reference match
 | 
					                    for (String status : searchPriority) {
 | 
				
			||||||
                            boolean isDirectMatch = referenceId.equals(logReferenceId);
 | 
					                        String[] targetStatuses = status.isEmpty() ? new String[]{} : new String[]{status};
 | 
				
			||||||
 | 
					                        String foundAcquirer = searchLogsByStatus(results, referenceId, targetStatuses);
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                            // Check custom_field1 for refresh tracking
 | 
					                        if (foundAcquirer != null && !foundAcquirer.isEmpty() && !foundAcquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
                            boolean isRefreshMatch = false;
 | 
					                            Log.d("ReceiptActivity", "🎯 Sync found acquirer: " + foundAcquirer + 
 | 
				
			||||||
                            String customField1 = reqBody.optString("custom_field1", "");
 | 
					                                " (priority: " + (status.isEmpty() ? "any" : status) + ")");
 | 
				
			||||||
                            if (!customField1.isEmpty()) {
 | 
					 | 
				
			||||||
                                try {
 | 
					 | 
				
			||||||
                                    org.json.JSONObject customData = new org.json.JSONObject(customField1);
 | 
					 | 
				
			||||||
                                    String originalReference = customData.optString("original_reference", "");
 | 
					 | 
				
			||||||
                                    String appReferenceId = customData.optString("app_reference_id", "");
 | 
					 | 
				
			||||||
                                    if (referenceId.equals(originalReference) || referenceId.equals(appReferenceId)) {
 | 
					 | 
				
			||||||
                                        isRefreshMatch = true;
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                } catch (org.json.JSONException e) {
 | 
					 | 
				
			||||||
                                    // Ignore parsing errors
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            
 | 
					 | 
				
			||||||
                            // Check if this log matches our reference
 | 
					 | 
				
			||||||
                            if (isDirectMatch || isRefreshMatch) {
 | 
					 | 
				
			||||||
                                // Prioritize settlement/success status
 | 
					 | 
				
			||||||
                                if (logTransactionStatus.equals("settlement") || 
 | 
					 | 
				
			||||||
                                    logTransactionStatus.equals("capture") ||
 | 
					 | 
				
			||||||
                                    logTransactionStatus.equals("success")) {
 | 
					 | 
				
			||||||
                                    
 | 
					 | 
				
			||||||
                                    // Extract acquirer (prefer acquirer field over issuer)
 | 
					 | 
				
			||||||
                                    String foundAcquirer = !logAcquirer.isEmpty() ? logAcquirer : logIssuer;
 | 
					 | 
				
			||||||
                                    if (!foundAcquirer.isEmpty() && !foundAcquirer.equalsIgnoreCase("qris")) {
 | 
					 | 
				
			||||||
                                        Log.d("ReceiptActivity", "📋 Sync found acquirer: " + foundAcquirer + " (status: " + logTransactionStatus + ")");
 | 
					 | 
				
			||||||
                            return foundAcquirer;
 | 
					                            return foundAcquirer;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    Log.w("ReceiptActivity", "⚠️ Sync search completed but no valid acquirer found");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                        }
 | 
					                
 | 
				
			||||||
                    }
 | 
					            } else {
 | 
				
			||||||
                }
 | 
					                Log.w("ReceiptActivity", "⚠️ Sync API call failed with code: " + conn.getResponseCode());
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
@ -470,15 +499,15 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Log.d("ReceiptActivity", "🔍 Async search for real acquirer: " + referenceId);
 | 
					                Log.d("ReceiptActivity", "🔍 Async search for real acquirer: " + referenceId);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                String queryUrl = "https://be-edc.msvc.app/api-logs?limit=100&sortOrder=DESC&sortColumn=created_at";
 | 
					                String queryUrl = "https://be-edc.msvc.app/api-logs?limit=200&sortOrder=DESC&sortColumn=created_at";
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                URL url = new URL(queryUrl);
 | 
					                URL url = new URL(queryUrl);
 | 
				
			||||||
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | 
					                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
 | 
				
			||||||
                conn.setRequestMethod("GET");
 | 
					                conn.setRequestMethod("GET");
 | 
				
			||||||
                conn.setRequestProperty("Accept", "application/json");
 | 
					                conn.setRequestProperty("Accept", "application/json");
 | 
				
			||||||
                conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
 | 
					                conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
 | 
				
			||||||
                conn.setConnectTimeout(10000);
 | 
					                conn.setConnectTimeout(15000);
 | 
				
			||||||
                conn.setReadTimeout(10000);
 | 
					                conn.setReadTimeout(15000);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                if (conn.getResponseCode() == 200) {
 | 
					                if (conn.getResponseCode() == 200) {
 | 
				
			||||||
                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 | 
					                    BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
 | 
				
			||||||
@ -492,63 +521,100 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
                    org.json.JSONArray results = json.optJSONArray("results");
 | 
					                    org.json.JSONArray results = json.optJSONArray("results");
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (results != null && results.length() > 0) {
 | 
					                    if (results != null && results.length() > 0) {
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "📊 Async analyzing " + results.length() + " webhook logs");
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
                        String realAcquirer = searchForRealAcquirer(results, referenceId);
 | 
					                        String realAcquirer = searchForRealAcquirer(results, referenceId);
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                        if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
 | 
					                        if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
                            Log.d("ReceiptActivity", "✅ Async found real acquirer: " + realAcquirer + " for reference: " + referenceId);
 | 
					                            Log.d("ReceiptActivity", "✅ Async found real acquirer: " + realAcquirer);
 | 
				
			||||||
                            
 | 
					                            
 | 
				
			||||||
                            // Update UI on main thread
 | 
					                            // Update UI on main thread
 | 
				
			||||||
                            final String displayAcquirer = getCardTypeFromAcquirer(realAcquirer, null, null);
 | 
					                            final String displayAcquirer = getCardTypeFromAcquirer(realAcquirer, null, null);
 | 
				
			||||||
                            runOnUiThread(() -> {
 | 
					                            runOnUiThread(() -> {
 | 
				
			||||||
                                if (cardType != null) {
 | 
					                                if (cardType != null) {
 | 
				
			||||||
                                    cardType.setText(displayAcquirer);
 | 
					                                    cardType.setText(displayAcquirer);
 | 
				
			||||||
                                    Log.d("ReceiptActivity", "🎨 Updated card type from QRIS to: " + displayAcquirer);
 | 
					                                    Log.d("ReceiptActivity", "🎨 UI UPDATED: QRIS -> " + displayAcquirer);
 | 
				
			||||||
 | 
					                                    
 | 
				
			||||||
 | 
					                                    // Show a subtle indication that the data was updated
 | 
				
			||||||
 | 
					                                    showToast("Card type updated: " + displayAcquirer);
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            });
 | 
					                            });
 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            Log.w("ReceiptActivity", "⚠️ Could not determine real acquirer for: " + referenceId);
 | 
					                            Log.w("ReceiptActivity", "⚠️ Async search found no valid acquirer for: " + referenceId);
 | 
				
			||||||
                            // Keep showing "QRIS" instead of defaulting to GoPay
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                    Log.w("ReceiptActivity", "⚠️ API call failed with code: " + conn.getResponseCode());
 | 
					                        Log.w("ReceiptActivity", "⚠️ Async search returned no results");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    Log.w("ReceiptActivity", "⚠️ Async API call failed with code: " + conn.getResponseCode());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
            } catch (Exception e) {
 | 
					            } catch (Exception e) {
 | 
				
			||||||
                Log.e("ReceiptActivity", "❌ Error fetching real acquirer: " + e.getMessage(), e);
 | 
					                Log.e("ReceiptActivity", "❌ Async acquirer fetch error: " + e.getMessage(), e);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }).start();
 | 
					        }).start();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * ✅ NEW METHOD: Advanced search for real acquirer in webhook logs
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private String searchForRealAcquirer(org.json.JSONArray results, String referenceId) {
 | 
					    private String searchForRealAcquirer(org.json.JSONArray results, String referenceId) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Log.d("ReceiptActivity", "🔍 Analyzing " + results.length() + " webhook logs for acquirer");
 | 
					            Log.d("ReceiptActivity", "🔍 Analyzing " + results.length() + " webhook logs for acquirer");
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🎯 Target reference ID: " + referenceId);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // Get order_id from intent for additional matching
 | 
				
			||||||
 | 
					            String orderId = getIntent().getStringExtra("order_id");
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🎯 Target order ID: " + orderId);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Strategy 1: Look for settlement/success transactions first (highest priority)
 | 
					            // Strategy 1: Look for settlement/success transactions first (highest priority)
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 Strategy 1: Searching for settlement/success status");
 | 
				
			||||||
            String acquirerFromSettlement = searchLogsByStatus(results, referenceId, new String[]{"settlement", "capture", "success"});
 | 
					            String acquirerFromSettlement = searchLogsByStatus(results, referenceId, new String[]{"settlement", "capture", "success"});
 | 
				
			||||||
            if (acquirerFromSettlement != null) {
 | 
					            if (acquirerFromSettlement != null) {
 | 
				
			||||||
                Log.d("ReceiptActivity", "🎯 Found acquirer from settlement: " + acquirerFromSettlement);
 | 
					                Log.d("ReceiptActivity", "🎯 SUCCESS: Found acquirer from settlement: " + acquirerFromSettlement);
 | 
				
			||||||
                return acquirerFromSettlement;
 | 
					                return acquirerFromSettlement;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Strategy 2: Look for pending transactions
 | 
					            // Strategy 2: Look for pending transactions
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 Strategy 2: Searching for pending status");
 | 
				
			||||||
            String acquirerFromPending = searchLogsByStatus(results, referenceId, new String[]{"pending"});
 | 
					            String acquirerFromPending = searchLogsByStatus(results, referenceId, new String[]{"pending"});
 | 
				
			||||||
            if (acquirerFromPending != null) {
 | 
					            if (acquirerFromPending != null) {
 | 
				
			||||||
                Log.d("ReceiptActivity", "🎯 Found acquirer from pending: " + acquirerFromPending);
 | 
					                Log.d("ReceiptActivity", "🎯 SUCCESS: Found acquirer from pending: " + acquirerFromPending);
 | 
				
			||||||
                return acquirerFromPending;
 | 
					                return acquirerFromPending;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // Strategy 3: Look for any transaction with this reference
 | 
					            // Strategy 3: Look for any transaction with this reference (broadest search)
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 Strategy 3: Searching for any status");
 | 
				
			||||||
            String acquirerFromAny = searchLogsByStatus(results, referenceId, new String[]{});
 | 
					            String acquirerFromAny = searchLogsByStatus(results, referenceId, new String[]{});
 | 
				
			||||||
            if (acquirerFromAny != null) {
 | 
					            if (acquirerFromAny != null) {
 | 
				
			||||||
                Log.d("ReceiptActivity", "🎯 Found acquirer from any status: " + acquirerFromAny);
 | 
					                Log.d("ReceiptActivity", "🎯 SUCCESS: Found acquirer from any status: " + acquirerFromAny);
 | 
				
			||||||
                return acquirerFromAny;
 | 
					                return acquirerFromAny;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            Log.w("ReceiptActivity", "❌ No acquirer found in webhook logs for: " + referenceId);
 | 
					            Log.w("ReceiptActivity", "❌ FAILED: No acquirer found in webhook logs for reference: " + referenceId);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            // Strategy 4: Debug logging - show what we actually found
 | 
				
			||||||
 | 
					            Log.d("ReceiptActivity", "🔍 DEBUG: Showing first 5 log entries for analysis:");
 | 
				
			||||||
 | 
					            for (int i = 0; i < Math.min(5, results.length()); i++) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    org.json.JSONObject log = results.getJSONObject(i);
 | 
				
			||||||
 | 
					                    org.json.JSONObject reqBody = log.optJSONObject("request_body");
 | 
				
			||||||
 | 
					                    if (reqBody != null) {
 | 
				
			||||||
 | 
					                        String logOrderId = reqBody.optString("order_id", "");
 | 
				
			||||||
 | 
					                        String logRefId = reqBody.optString("reference_id", "");
 | 
				
			||||||
 | 
					                        String logStatus = reqBody.optString("transaction_status", "");
 | 
				
			||||||
 | 
					                        String logAcquirer = reqBody.optString("acquirer", "");
 | 
				
			||||||
 | 
					                        String logIssuer = reqBody.optString("issuer", "");
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "   Log " + (i+1) + ": " +
 | 
				
			||||||
 | 
					                            "order_id=" + logOrderId + 
 | 
				
			||||||
 | 
					                            ", ref_id=" + logRefId +
 | 
				
			||||||
 | 
					                            ", status=" + logStatus +
 | 
				
			||||||
 | 
					                            ", acquirer=" + logAcquirer +
 | 
				
			||||||
 | 
					                            ", issuer=" + logIssuer);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } catch (Exception e) {
 | 
				
			||||||
 | 
					                    Log.w("ReceiptActivity", "Error parsing debug log " + i + ": " + e.getMessage());
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
            return null;
 | 
					            return null;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
@ -557,9 +623,6 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * ✅ HELPER METHOD: Search logs by specific status
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private String searchLogsByStatus(org.json.JSONArray results, String referenceId, String[] targetStatuses) {
 | 
					    private String searchLogsByStatus(org.json.JSONArray results, String referenceId, String[] targetStatuses) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            for (int i = 0; i < results.length(); i++) {
 | 
					            for (int i = 0; i < results.length(); i++) {
 | 
				
			||||||
@ -571,10 +634,24 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
                    String logTransactionStatus = reqBody.optString("transaction_status", "");
 | 
					                    String logTransactionStatus = reqBody.optString("transaction_status", "");
 | 
				
			||||||
                    String logAcquirer = reqBody.optString("acquirer", "");
 | 
					                    String logAcquirer = reqBody.optString("acquirer", "");
 | 
				
			||||||
                    String logIssuer = reqBody.optString("issuer", "");
 | 
					                    String logIssuer = reqBody.optString("issuer", "");
 | 
				
			||||||
 | 
					                    String logOrderId = reqBody.optString("order_id", "");
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    Log.d("ReceiptActivity", "🔍 Checking log: order_id=" + logOrderId + 
 | 
				
			||||||
 | 
					                        ", status=" + logTransactionStatus + 
 | 
				
			||||||
 | 
					                        ", acquirer=" + logAcquirer + 
 | 
				
			||||||
 | 
					                        ", issuer=" + logIssuer);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    // Check for direct reference match
 | 
					                    // Check for direct reference match
 | 
				
			||||||
                    boolean isDirectMatch = referenceId.equals(logReferenceId);
 | 
					                    boolean isDirectMatch = referenceId.equals(logReferenceId);
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
 | 
					                    // ✅ IMPROVED: Also check order_id match from QrisResultActivity
 | 
				
			||||||
 | 
					                    boolean isOrderMatch = false;
 | 
				
			||||||
 | 
					                    String orderId = getIntent().getStringExtra("order_id");
 | 
				
			||||||
 | 
					                    if (orderId != null && !orderId.isEmpty() && orderId.equals(logOrderId)) {
 | 
				
			||||||
 | 
					                        isOrderMatch = true;
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "✅ Found order_id match: " + orderId);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                    // Check custom_field1 for refresh tracking
 | 
					                    // Check custom_field1 for refresh tracking
 | 
				
			||||||
                    boolean isRefreshMatch = false;
 | 
					                    boolean isRefreshMatch = false;
 | 
				
			||||||
                    String customField1 = reqBody.optString("custom_field1", "");
 | 
					                    String customField1 = reqBody.optString("custom_field1", "");
 | 
				
			||||||
@ -592,7 +669,13 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    // Check if this log matches our reference
 | 
					                    // Check if this log matches our reference
 | 
				
			||||||
                    if (isDirectMatch || isRefreshMatch) {
 | 
					                    if (isDirectMatch || isRefreshMatch || isOrderMatch) {
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "🎯 TRANSACTION MATCH FOUND!");
 | 
				
			||||||
 | 
					                        Log.d("ReceiptActivity", "   Match type: " + 
 | 
				
			||||||
 | 
					                            (isDirectMatch ? "DIRECT " : "") + 
 | 
				
			||||||
 | 
					                            (isRefreshMatch ? "REFRESH " : "") + 
 | 
				
			||||||
 | 
					                            (isOrderMatch ? "ORDER" : ""));
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
                        // If target statuses specified, check status
 | 
					                        // If target statuses specified, check status
 | 
				
			||||||
                        if (targetStatuses.length > 0) {
 | 
					                        if (targetStatuses.length > 0) {
 | 
				
			||||||
                            boolean statusMatches = false;
 | 
					                            boolean statusMatches = false;
 | 
				
			||||||
@ -602,14 +685,47 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
                                    break;
 | 
					                                    break;
 | 
				
			||||||
                                }
 | 
					                                }
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            if (!statusMatches) continue; // Skip if status doesn't match
 | 
					                            if (!statusMatches) {
 | 
				
			||||||
 | 
					                                Log.d("ReceiptActivity", "   Status doesn't match target: " + logTransactionStatus);
 | 
				
			||||||
 | 
					                                continue; // Skip if status doesn't match
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        
 | 
					                        
 | 
				
			||||||
                        // Extract acquirer (prefer acquirer field over issuer)
 | 
					                        // ✅ CRITICAL FIX: For QRIS transactions, prioritize issuer over acquirer
 | 
				
			||||||
                        String foundAcquirer = !logAcquirer.isEmpty() ? logAcquirer : logIssuer;
 | 
					                        String foundAcquirer = null;
 | 
				
			||||||
                        if (!foundAcquirer.isEmpty() && !foundAcquirer.equalsIgnoreCase("qris")) {
 | 
					                        
 | 
				
			||||||
                            Log.d("ReceiptActivity", "📋 Found acquirer: " + foundAcquirer + " (status: " + logTransactionStatus + ")");
 | 
					                        // Check if this is a QRIS transaction by payment_type
 | 
				
			||||||
 | 
					                        String paymentType = reqBody.optString("payment_type", "");
 | 
				
			||||||
 | 
					                        boolean isQrisTransaction = "qris".equalsIgnoreCase(paymentType);
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        if (isQrisTransaction) {
 | 
				
			||||||
 | 
					                            // For QRIS: issuer contains the actual payment provider (LinkAja, DANA, etc.)
 | 
				
			||||||
 | 
					                            // acquirer is usually just "gopay" (the QRIS aggregator)
 | 
				
			||||||
 | 
					                            if (!logIssuer.isEmpty() && !logIssuer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
 | 
					                                foundAcquirer = logIssuer;
 | 
				
			||||||
 | 
					                                Log.d("ReceiptActivity", "📱 QRIS: Using issuer as acquirer: " + foundAcquirer);
 | 
				
			||||||
 | 
					                            } else if (!logAcquirer.isEmpty() && !logAcquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
 | 
					                                foundAcquirer = logAcquirer;
 | 
				
			||||||
 | 
					                                Log.d("ReceiptActivity", "📱 QRIS: Fallback to acquirer: " + foundAcquirer);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            // For non-QRIS: prefer acquirer over issuer (traditional behavior)
 | 
				
			||||||
 | 
					                            if (!logAcquirer.isEmpty() && !logAcquirer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
 | 
					                                foundAcquirer = logAcquirer;
 | 
				
			||||||
 | 
					                                Log.d("ReceiptActivity", "💳 Non-QRIS: Using acquirer: " + foundAcquirer);
 | 
				
			||||||
 | 
					                            } else if (!logIssuer.isEmpty() && !logIssuer.equalsIgnoreCase("qris")) {
 | 
				
			||||||
 | 
					                                foundAcquirer = logIssuer;
 | 
				
			||||||
 | 
					                                Log.d("ReceiptActivity", "💳 Non-QRIS: Fallback to issuer: " + foundAcquirer);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        if (foundAcquirer != null && !foundAcquirer.isEmpty()) {
 | 
				
			||||||
 | 
					                            Log.d("ReceiptActivity", "✅ FINAL ACQUIRER FOUND: " + foundAcquirer + 
 | 
				
			||||||
 | 
					                                " (status: " + logTransactionStatus + 
 | 
				
			||||||
 | 
					                                ", payment_type: " + paymentType + ")");
 | 
				
			||||||
                            return foundAcquirer;
 | 
					                            return foundAcquirer;
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            Log.w("ReceiptActivity", "⚠️ Transaction matched but no valid acquirer found");
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@ -626,7 +742,18 @@ public class ReceiptActivity extends AppCompatActivity {
 | 
				
			|||||||
        if (input == null || input.isEmpty()) {
 | 
					        if (input == null || input.isEmpty()) {
 | 
				
			||||||
            return input;
 | 
					            return input;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase();
 | 
					        
 | 
				
			||||||
 | 
					        // Handle special cases
 | 
				
			||||||
 | 
					        String cleaned = input.trim();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Special handling for common patterns
 | 
				
			||||||
 | 
					        if (cleaned.toLowerCase().contains("pay")) {
 | 
				
			||||||
 | 
					            // Keep "Pay" capitalized in payment methods
 | 
				
			||||||
 | 
					            return cleaned.substring(0, 1).toUpperCase() + cleaned.substring(1).toLowerCase()
 | 
				
			||||||
 | 
					                .replace("pay", "Pay");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return cleaned.substring(0, 1).toUpperCase() + cleaned.substring(1).toLowerCase();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private void setAmountData(String amount, String grossAmount) {
 | 
					    private void setAmountData(String amount, String grossAmount) {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user