Result Transaction dan QRIS

This commit is contained in:
riz081 2025-06-27 17:01:05 +07:00
parent b66ef4bb00
commit 53964211c2
4 changed files with 579 additions and 537 deletions

View File

@ -23,6 +23,8 @@ import java.net.HttpURLConnection;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.URL; import java.net.URL;
import java.net.URI; import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import com.example.bdkipoc.cetakulang.ReprintActivity; import com.example.bdkipoc.cetakulang.ReprintActivity;
@ -52,6 +54,28 @@ public class ReceiptActivity extends AppCompatActivity {
private LinearLayout emailButton; private LinearLayout emailButton;
private Button finishButton; private Button finishButton;
// ENHANCED: Mapping dari technical issuer ke display name
private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{
put("airpay shopee", "ShopeePay");
put("shopeepay", "ShopeePay");
put("shopee", "ShopeePay");
put("linkaja", "LinkAja");
put("link aja", "LinkAja");
put("dana", "DANA");
put("ovo", "OVO");
put("gopay", "GoPay");
put("jenius", "Jenius");
put("sakuku", "Sakuku");
put("bni", "BNI");
put("bca", "BCA");
put("mandiri", "Mandiri");
put("bri", "BRI");
put("cimb", "CIMB Niaga");
put("permata", "Permata");
put("maybank", "Maybank");
put("qris", "QRIS");
}};
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -118,10 +142,27 @@ public class ReceiptActivity extends AppCompatActivity {
finishButton.setOnClickListener(v -> handleFinish()); finishButton.setOnClickListener(v -> handleFinish());
} }
/**
* ENHANCED: Load transaction data with support for both EMV/Card and QRIS
*/
private void loadTransactionData() { private void loadTransactionData() {
Intent intent = getIntent(); Intent intent = getIntent();
if (intent != null) { if (intent != null) {
Log.d("ReceiptActivity", "=== LOADING TRANSACTION DATA ==="); Log.d("ReceiptActivity", "=== LOADING ENHANCED TRANSACTION DATA ===");
// DETECT TRANSACTION TYPE
String callingActivity = intent.getStringExtra("calling_activity");
String channelCategory = intent.getStringExtra("channel_category");
String channelCode = intent.getStringExtra("channel_code");
boolean isEmvTransaction = "EMV_CARD".equals(channelCategory) || "ResultTransactionActivity".equals(callingActivity);
boolean isQrisTransaction = "QRIS".equalsIgnoreCase(channelCode) || "QrisResultActivity".equals(callingActivity);
Log.d("ReceiptActivity", "🔍 TRANSACTION TYPE DETECTION:");
Log.d("ReceiptActivity", " Calling Activity: " + callingActivity);
Log.d("ReceiptActivity", " Channel Category: " + channelCategory);
Log.d("ReceiptActivity", " Channel Code: " + channelCode);
Log.d("ReceiptActivity", " Is EMV Transaction: " + isEmvTransaction);
Log.d("ReceiptActivity", " Is QRIS Transaction: " + isQrisTransaction);
// Get all available data from intent // Get all available data from intent
String amount = intent.getStringExtra("transaction_amount"); String amount = intent.getStringExtra("transaction_amount");
@ -135,89 +176,144 @@ public class ReceiptActivity extends AppCompatActivity {
String createdAt = intent.getStringExtra("created_at"); String createdAt = intent.getStringExtra("created_at");
String paymentMethodStr = intent.getStringExtra("payment_method"); String paymentMethodStr = intent.getStringExtra("payment_method");
String cardTypeStr = intent.getStringExtra("card_type"); String cardTypeStr = intent.getStringExtra("card_type");
String channelCode = intent.getStringExtra("channel_code");
String channelCategory = intent.getStringExtra("channel_category");
String acquirer = intent.getStringExtra("acquirer"); String acquirer = intent.getStringExtra("acquirer");
String mid = intent.getStringExtra("mid"); String mid = intent.getStringExtra("mid");
String tid = intent.getStringExtra("tid"); String tid = intent.getStringExtra("tid");
// EMV SPECIFIC DATA
String emvCardholderName = intent.getStringExtra("emv_cardholder_name");
String emvAid = intent.getStringExtra("emv_aid");
String emvExpiry = intent.getStringExtra("emv_expiry");
String cardNumber = intent.getStringExtra("card_number");
String midtransResponse = intent.getStringExtra("midtrans_response");
boolean emvMode = intent.getBooleanExtra("emv_mode", false);
// QRIS SPECIFIC DATA
String qrString = intent.getStringExtra("qr_string");
// Log received data for debugging // Log received data for debugging
Log.d("ReceiptActivity", "🔍 RECEIVED DATA:"); Log.d("ReceiptActivity", "🔍 RECEIVED DATA:");
Log.d("ReceiptActivity", " amount: " + amount); Log.d("ReceiptActivity", " amount: " + amount);
Log.d("ReceiptActivity", " referenceId: " + referenceId); Log.d("ReceiptActivity", " referenceId: " + referenceId);
Log.d("ReceiptActivity", " orderId: " + orderId); Log.d("ReceiptActivity", " orderId: " + orderId);
Log.d("ReceiptActivity", " channelCode: " + channelCode);
Log.d("ReceiptActivity", " acquirer (from intent): " + acquirer); Log.d("ReceiptActivity", " acquirer (from intent): " + acquirer);
Log.d("ReceiptActivity", " createdAt: " + createdAt); Log.d("ReceiptActivity", " createdAt: " + createdAt);
Log.d("ReceiptActivity", " EMV Mode: " + emvMode);
Log.d("ReceiptActivity", " EMV Cardholder: " + emvCardholderName);
Log.d("ReceiptActivity", " Card Number: " + (cardNumber != null ? cardNumber : "N/A"));
Log.d("ReceiptActivity", " QR String Available: " + (qrString != null && !qrString.isEmpty()));
// 1. Set merchant data with defaults // 1. Set merchant data with defaults
merchantName.setText(merchantNameStr != null ? merchantNameStr : "Marcel Panjaitan"); merchantName.setText(merchantNameStr != null ? merchantNameStr : "TOKO KLONTONG PAK EKO");
merchantLocation.setText(merchantLocationStr != null ? merchantLocationStr : "Jakarta, Indonesia"); merchantLocation.setText(merchantLocationStr != null ? merchantLocationStr : "Ciputat Baru, Tangsel");
// 2. Set MID and TID // 2. Set MID and TID
midText.setText(mid != null ? mid : "71000026521"); midText.setText("MID: " + (mid != null ? mid : "123456789901"));
tidText.setText(tid != null ? tid : "73001500"); tidText.setText("TID: " + (tid != null ? tid : "123456789901"));
// 3. Set transaction number // 3. Set transaction number
String displayTransactionNumber = null; String displayTransactionNumber = getDisplayTransactionNumber(referenceId, transactionId, orderId);
if (referenceId != null && !referenceId.isEmpty()) { transactionNumber.setText(displayTransactionNumber);
displayTransactionNumber = referenceId;
} else if (transactionId != null && !transactionId.isEmpty()) {
displayTransactionNumber = transactionId;
} else if (orderId != null && !orderId.isEmpty()) {
displayTransactionNumber = orderId;
}
transactionNumber.setText(displayTransactionNumber != null ? displayTransactionNumber : "N/A");
// 4. Set transaction date // 4. Set transaction date
String displayDate = null; String displayDate = getDisplayTransactionDate(createdAt, transactionDateStr, isEmvTransaction);
if (createdAt != null && !createdAt.isEmpty()) {
displayDate = formatDateFromCreatedAt(createdAt);
} else if (transactionDateStr != null && !transactionDateStr.isEmpty()) {
displayDate = transactionDateStr;
} else {
displayDate = getCurrentDateTime();
}
transactionDate.setText(displayDate); transactionDate.setText(displayDate);
// 5. Set payment method // 5. ENHANCED: Set payment method based on transaction type
String displayPaymentMethod = getPaymentMethodFromChannelCode(channelCode, paymentMethodStr); String displayPaymentMethod = getDisplayPaymentMethod(channelCode, paymentMethodStr, isEmvTransaction, emvMode);
paymentMethod.setText(displayPaymentMethod); paymentMethod.setText(displayPaymentMethod);
// 6. IMPROVED: Enhanced card type detection for QRIS // 6. ENHANCED: Set card type with EMV and QRIS priority
String displayCardType = null; String displayCardType = getDisplayCardType(cardTypeStr, acquirer, channelCode, isEmvTransaction,
isQrisTransaction, midtransResponse, referenceId);
cardType.setText(displayCardType);
if (channelCode != null && channelCode.equalsIgnoreCase("QRIS")) { // 7. Format and set amounts with proper calculation
Log.d("ReceiptActivity", "🔍 QRIS transaction detected - searching for real acquirer"); setAmountDataEnhanced(amount, grossAmount, isEmvTransaction, isQrisTransaction);
// For QRIS, try to get real acquirer from webhook data Log.d("ReceiptActivity", "💳 FINAL DISPLAY VALUES:");
if (referenceId != null && !referenceId.isEmpty()) { Log.d("ReceiptActivity", " Payment Method: " + displayPaymentMethod);
String realAcquirer = fetchRealAcquirerSync(referenceId); Log.d("ReceiptActivity", " Card Type: " + displayCardType);
if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) { Log.d("ReceiptActivity", " Transaction Number: " + displayTransactionNumber);
displayCardType = getCardTypeFromAcquirer(realAcquirer, null, null); Log.d("ReceiptActivity", "=== ENHANCED TRANSACTION DATA LOADED ===");
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); * Get display transaction number with priority
} */
} else { private String getDisplayTransactionNumber(String referenceId, String transactionId, String orderId) {
displayCardType = "QRIS"; if (referenceId != null && !referenceId.isEmpty()) {
} return referenceId;
} else if (transactionId != null && !transactionId.isEmpty()) {
// For long transaction IDs, show last 10 characters
return transactionId.length() > 10 ?
transactionId.substring(transactionId.length() - 10) : transactionId;
} else if (orderId != null && !orderId.isEmpty()) {
return orderId.length() > 10 ?
orderId.substring(orderId.length() - 10) : orderId;
}
return String.valueOf(System.currentTimeMillis() % 10000000000L);
}
/**
* Get display transaction date with proper formatting
*/
private String getDisplayTransactionDate(String createdAt, String transactionDateStr, boolean isEmvTransaction) {
String dateToFormat = null;
if (createdAt != null && !createdAt.isEmpty()) {
dateToFormat = createdAt;
} else if (transactionDateStr != null && !transactionDateStr.isEmpty()) {
dateToFormat = transactionDateStr;
}
if (dateToFormat != null) {
if (isEmvTransaction) {
return formatDateForEmvTransaction(dateToFormat);
} else { } else {
// Non-QRIS transaction return formatDateFromCreatedAt(dateToFormat);
displayCardType = getCardTypeFromAcquirer(acquirer, channelCode, cardTypeStr); }
}
return getCurrentDateTime();
}
/**
* Format date specifically for EMV transactions
*/
private String formatDateForEmvTransaction(String dateString) {
try {
// EMV transactions might use different date formats
String[] inputFormats = {
"dd MMMM yyyy HH:mm",
"yyyy-MM-dd HH:mm:ss",
"yyyy-MM-dd'T'HH:mm:ss'Z'",
"dd/MM/yyyy HH:mm"
};
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
for (String format : inputFormats) {
try {
SimpleDateFormat inputFormat = new SimpleDateFormat(format,
format.contains("MMMM") ? new Locale("id", "ID") : Locale.getDefault());
Date date = inputFormat.parse(dateString);
String formatted = outputFormat.format(date);
Log.d("ReceiptActivity", "EMV Date formatting: '" + dateString + "' -> '" + formatted + "'");
return formatted;
} catch (Exception ignored) {
// Try next format
}
} }
cardType.setText(displayCardType); // If all formats fail, return as-is
Log.d("ReceiptActivity", "💳 FINAL CARD TYPE: " + displayCardType); Log.w("ReceiptActivity", "Could not format EMV date: " + dateString);
return dateString;
// 7. Format and set amounts } catch (Exception e) {
setAmountData(amount, grossAmount); Log.e("ReceiptActivity", "Error formatting EMV date: " + dateString, e);
return dateString;
Log.d("ReceiptActivity", "=== TRANSACTION DATA LOADED ===");
} }
} }
@ -227,7 +323,7 @@ public class ReceiptActivity extends AppCompatActivity {
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
// Output format for receipt: "dd/MM/yyyy HH:mm" // Output format for receipt: "dd/MM/yyyy HH:mm"
SimpleDateFormat outputFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm", new Locale("id", "ID")); SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
Date date = inputFormat.parse(createdAt); Date date = inputFormat.parse(createdAt);
String formatted = outputFormat.format(date); String formatted = outputFormat.format(date);
@ -242,6 +338,39 @@ public class ReceiptActivity extends AppCompatActivity {
} }
} }
/**
* Get display payment method with EMV support
*/
private String getDisplayPaymentMethod(String channelCode, String fallbackPaymentMethod,
boolean isEmvTransaction, boolean emvMode) {
if (isEmvTransaction) {
// For EMV transactions, be more specific
if (emvMode) {
if (channelCode != null) {
switch (channelCode.toUpperCase()) {
case "CREDIT": return "Kartu Kredit (EMV)";
case "DEBIT": return "Kartu Debit (EMV)";
default: return "Kartu Kredit (EMV)";
}
}
return "Kartu Kredit (EMV)";
} else {
// Magnetic stripe
if (channelCode != null) {
switch (channelCode.toUpperCase()) {
case "CREDIT": return "Kartu Kredit";
case "DEBIT": return "Kartu Debit";
default: return "Kartu Kredit";
}
}
return "Kartu Kredit";
}
} else {
// For QRIS and other transactions, use existing logic
return getPaymentMethodFromChannelCode(channelCode, fallbackPaymentMethod);
}
}
/** /**
* Get payment method name from channel_code with comprehensive mapping * Get payment method name from channel_code with comprehensive mapping
*/ */
@ -291,6 +420,78 @@ public class ReceiptActivity extends AppCompatActivity {
return fallbackPaymentMethod != null ? fallbackPaymentMethod : "QRIS"; return fallbackPaymentMethod != null ? fallbackPaymentMethod : "QRIS";
} }
/**
* ENHANCED: Card type detection with EMV and QRIS priority
*/
private String getDisplayCardType(String cardTypeStr, String acquirer, String channelCode,
boolean isEmvTransaction, boolean isQrisTransaction,
String midtransResponse, String referenceId) {
Log.d("ReceiptActivity", "🔍 ENHANCED CARD TYPE DETECTION:");
Log.d("ReceiptActivity", " Input Card Type: " + cardTypeStr);
Log.d("ReceiptActivity", " Input Acquirer: " + acquirer);
Log.d("ReceiptActivity", " Is EMV Transaction: " + isEmvTransaction);
Log.d("ReceiptActivity", " Is QRIS Transaction: " + isQrisTransaction);
if (isEmvTransaction) {
// FOR EMV TRANSACTIONS: Priority to cardTypeStr from ResultTransactionActivity
if (cardTypeStr != null && !cardTypeStr.isEmpty() && !cardTypeStr.equalsIgnoreCase("unknown")) {
Log.d("ReceiptActivity", "✅ EMV: Using provided card type: " + cardTypeStr);
return cardTypeStr;
}
// FALLBACK: Try to extract from Midtrans response
if (midtransResponse != null && !midtransResponse.isEmpty()) {
String bankFromMidtrans = extractBankFromMidtransResponse(midtransResponse);
if (bankFromMidtrans != null && !bankFromMidtrans.isEmpty()) {
Log.d("ReceiptActivity", "✅ EMV: Using bank from Midtrans response: " + bankFromMidtrans);
return bankFromMidtrans;
}
}
// FALLBACK: Use acquirer
if (acquirer != null && !acquirer.isEmpty() && !acquirer.equalsIgnoreCase("qris")) {
String mappedAcquirer = getCardTypeFromAcquirer(acquirer, channelCode, null);
Log.d("ReceiptActivity", "✅ EMV: Using mapped acquirer: " + mappedAcquirer);
return mappedAcquirer;
}
Log.d("ReceiptActivity", "⚠️ EMV: Using default fallback: BCA");
return "BCA"; // Default for EMV
} else if (isQrisTransaction) {
// FOR QRIS TRANSACTIONS: Enhanced detection
Log.d("ReceiptActivity", "🔍 QRIS transaction detected - searching for real acquirer");
// Priority 1: Use provided cardTypeStr if it's not generic
if (cardTypeStr != null && !cardTypeStr.isEmpty() &&
!cardTypeStr.equalsIgnoreCase("qris") && !cardTypeStr.equalsIgnoreCase("unknown")) {
Log.d("ReceiptActivity", "✅ QRIS: Using provided specific card type: " + cardTypeStr);
return cardTypeStr;
}
// Priority 2: Search webhook logs for real acquirer
if (referenceId != null && !referenceId.isEmpty()) {
String realAcquirer = fetchRealAcquirerSync(referenceId);
if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
String mappedQrisAcquirer = getCardTypeFromAcquirer(realAcquirer, null, null);
Log.d("ReceiptActivity", "✅ QRIS real acquirer found: " + realAcquirer + " -> " + mappedQrisAcquirer);
return mappedQrisAcquirer;
} else {
Log.w("ReceiptActivity", "⚠️ QRIS real acquirer not found, using generic QRIS");
// Start async search for better results
fetchRealAcquirerFromWebhook(referenceId);
return "QRIS";
}
} else {
return "QRIS";
}
} else {
// FOR OTHER TRANSACTIONS: Use standard logic
return getCardTypeFromAcquirer(acquirer, channelCode, cardTypeStr);
}
}
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")) {
@ -299,88 +500,14 @@ public class ReceiptActivity extends AppCompatActivity {
Log.d("ReceiptActivity", "🔍 Mapping acquirer: '" + acquirer + "' -> '" + acq + "'"); Log.d("ReceiptActivity", "🔍 Mapping acquirer: '" + acquirer + "' -> '" + acq + "'");
// COMPREHENSIVE acquirer mapping (case-insensitive) // COMPREHENSIVE acquirer mapping (case-insensitive)
String mappedName = ISSUER_DISPLAY_MAP.get(acq);
if (mappedName != null) {
Log.d("ReceiptActivity", "✅ Mapped acquirer: " + acquirer + " -> " + mappedName);
return mappedName;
}
// Additional mapping for variations not in the map
switch (acq) { switch (acq) {
// E-Wallet acquirers (most common for QRIS)
case "gopay":
case "go-pay":
case "gojek": return "GoPay";
case "shopeepay":
case "shopee_pay":
case "shopee": return "ShopeePay";
case "ovo": return "OVO";
case "dana": return "DANA";
case "linkaja":
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
case "bca":
case "bank_bca": return "BCA";
case "mandiri":
case "bank_mandiri":
case "mandiri_bill": return "Mandiri";
case "bni":
case "bank_bni":
case "bni_va": return "BNI";
case "bri":
case "bank_bri":
case "bri_va": return "BRI";
case "permata":
case "bank_permata":
case "permata_va": return "Permata";
case "cimb":
case "cimb_niaga":
case "bank_cimb":
case "cimb_va": return "CIMB Niaga";
case "danamon":
case "bank_danamon":
case "danamon_va": return "Danamon";
case "bsi":
case "bank_bsi":
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": case "mastercard":
@ -740,6 +867,78 @@ public class ReceiptActivity extends AppCompatActivity {
return null; // No acquirer found for specified criteria return null; // No acquirer found for specified criteria
} }
/**
* Extract bank from Midtrans response JSON string
*/
private String extractBankFromMidtransResponse(String midtransResponse) {
try {
org.json.JSONObject response = new org.json.JSONObject(midtransResponse);
// Try different possible bank fields
String[] bankFields = {"bank", "issuer", "acquiring_bank", "issuer_bank"};
for (String field : bankFields) {
if (response.has(field)) {
String bankValue = response.getString(field);
if (bankValue != null && !bankValue.trim().isEmpty() && !bankValue.equalsIgnoreCase("qris")) {
Log.d("ReceiptActivity", "Found bank in Midtrans response (" + field + "): " + bankValue);
return formatBankNameForReceipt(bankValue);
}
}
}
Log.w("ReceiptActivity", "No valid bank found in Midtrans response");
return null;
} catch (Exception e) {
Log.e("ReceiptActivity", "Error extracting bank from Midtrans response: " + e.getMessage());
return null;
}
}
/**
* Format bank name specifically for receipt display
*/
private String formatBankNameForReceipt(String bankName) {
if (bankName == null || bankName.trim().isEmpty()) {
return "BCA"; // Default
}
String formatted = bankName.trim();
// Common bank name mappings for receipt display
switch (formatted.toUpperCase()) {
case "BCA":
case "BANK BCA":
case "BANK CENTRAL ASIA": return "BCA";
case "MANDIRI":
case "BANK MANDIRI": return "Mandiri";
case "BNI":
case "BANK BNI":
case "BANK NEGARA INDONESIA": return "BNI";
case "BRI":
case "BANK BRI":
case "BANK RAKYAT INDONESIA": return "BRI";
case "CIMB":
case "CIMB NIAGA":
case "BANK CIMB NIAGA": return "CIMB Niaga";
case "DANAMON":
case "BANK DANAMON": return "Danamon";
case "PERMATA":
case "BANK PERMATA": return "Permata";
default:
// Return capitalized version
return capitalizeFirstLetter(formatted);
}
}
private String capitalizeFirstLetter(String input) { private String capitalizeFirstLetter(String input) {
if (input == null || input.isEmpty()) { if (input == null || input.isEmpty()) {
return input; return input;
@ -758,51 +957,79 @@ public class ReceiptActivity extends AppCompatActivity {
return cleaned.substring(0, 1).toUpperCase() + cleaned.substring(1).toLowerCase(); return cleaned.substring(0, 1).toUpperCase() + cleaned.substring(1).toLowerCase();
} }
private void setAmountData(String amount, String grossAmount) { /**
// Prioritize 'amount' over 'grossAmount' for transaction data * ENHANCED: Set amount data with EMV and QRIS support
*/
private void setAmountDataEnhanced(String amount, String grossAmount, boolean isEmvTransaction, boolean isQrisTransaction) {
String amountToUse = amount != null ? amount : grossAmount; String amountToUse = amount != null ? amount : grossAmount;
Log.d("ReceiptActivity", "Setting amount data - amount: " + amount + Log.d("ReceiptActivity", "Setting enhanced amount data - amount: " + amount +
", grossAmount: " + grossAmount + ", using: " + amountToUse); ", grossAmount: " + grossAmount + ", using: " + amountToUse +
", isEMV: " + isEmvTransaction + ", isQRIS: " + isQrisTransaction);
if (amountToUse != null) { if (amountToUse != null) {
try { try {
// Clean and parse the amount
String cleanAmount = cleanAmountString(amountToUse); String cleanAmount = cleanAmountString(amountToUse);
Log.d("ReceiptActivity", "Cleaned amount: " + cleanAmount); Log.d("ReceiptActivity", "Cleaned amount: " + cleanAmount);
// Parse as long integer (Indonesian Rupiah doesn't use decimal cents)
long amountLong = Long.parseLong(cleanAmount); long amountLong = Long.parseLong(cleanAmount);
// Set transaction total // Set transaction total
transactionTotal.setText("Rp " + formatCurrency(amountLong)); transactionTotal.setText(formatCurrency(amountLong));
// Calculate tax and service fee (for QRIS, typically no additional fees) // CALCULATE FEES BASED ON TRANSACTION TYPE
long tax = 0; // QRIS usually doesn't have tax long tax = 0;
long serviceFeeValue = 0; // QRIS usually doesn't have service fee long serviceFeeValue = 0;
long total = amountLong + tax + serviceFeeValue; long total = amountLong;
if (isEmvTransaction) {
// For EMV transactions, check if gross amount includes additional fees
if (grossAmount != null && !grossAmount.equals(amount)) {
try {
long grossAmountLong = Long.parseLong(cleanAmountString(grossAmount));
long difference = grossAmountLong - amountLong;
if (difference > 0) {
// Assume 11% tax and 500 service fee (adjust based on your business logic)
tax = Math.round(amountLong * 0.11);
serviceFeeValue = 500;
total = grossAmountLong;
Log.d("ReceiptActivity", "EMV: Calculated tax=" + tax + ", service=" + serviceFeeValue + ", total=" + total);
}
} catch (Exception e) {
Log.w("ReceiptActivity", "Could not parse gross amount for EMV: " + grossAmount);
}
}
} else if (isQrisTransaction) {
// For QRIS, typically no additional fees (tax=0, service=0)
tax = 0;
serviceFeeValue = 0;
total = amountLong;
Log.d("ReceiptActivity", "QRIS: No additional fees - total=" + total);
}
// Set calculated values // Set calculated values
taxPercentage.setText("Rp 0"); taxPercentage.setText(tax > 0 ? "11%" : "0%");
serviceFee.setText("Rp 0"); serviceFee.setText(formatCurrency(serviceFeeValue));
finalTotal.setText("Rp " + formatCurrency(total)); finalTotal.setText(formatCurrency(total));
Log.d("ReceiptActivity", "Amount formatting successful: " + amountLong + " -> Rp " + formatCurrency(total)); Log.d("ReceiptActivity", "Enhanced amount formatting successful: " + amountLong + " -> " + formatCurrency(total));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
Log.e("ReceiptActivity", "Error parsing amount: " + amountToUse, e); Log.e("ReceiptActivity", "Error parsing enhanced amount: " + amountToUse, e);
// Fallback if parsing fails // Fallback if parsing fails
transactionTotal.setText("Rp " + amountToUse); transactionTotal.setText(amountToUse);
taxPercentage.setText("Rp 0"); taxPercentage.setText("0%");
serviceFee.setText("Rp 0"); serviceFee.setText("0");
finalTotal.setText("Rp " + amountToUse); finalTotal.setText(amountToUse);
} }
} else { } else {
// Default values if no amount provided // Default values if no amount provided
transactionTotal.setText("Rp 0"); transactionTotal.setText("0");
taxPercentage.setText("Rp 0"); taxPercentage.setText("0%");
serviceFee.setText("Rp 0"); serviceFee.setText("0");
finalTotal.setText("Rp 0"); finalTotal.setText("0");
} }
} }
@ -876,7 +1103,7 @@ public class ReceiptActivity extends AppCompatActivity {
} }
private String getCurrentDateTime() { private String getCurrentDateTime() {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm", new Locale("id", "ID")); SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
return sdf.format(new Date()); return sdf.format(new Date());
} }
@ -916,6 +1143,11 @@ public class ReceiptActivity extends AppCompatActivity {
navigateToHomePage(); navigateToHomePage();
break; break;
case "ResultTransactionActivity":
// NEW: Handle back from ResultTransactionActivity
navigateToHomePage();
break;
case "PaymentActivity": case "PaymentActivity":
case "QrisActivity": case "QrisActivity":
// Go back to payment/qris activity // Go back to payment/qris activity

View File

@ -78,15 +78,15 @@ public class QrisResultActivity extends AppCompatActivity {
private String currentQrImageUrl; private String currentQrImageUrl;
private int originalAmount; private int originalAmount;
// ADD: QR String untuk validasi QRIS // QR String untuk validasi QRIS
private String currentQrString = ""; private String currentQrString = "";
private String qrStringFromMidtrans = ""; private String qrStringFromMidtrans = "";
// FIXED: Store actual issuer/acquirer from Midtrans response // Store actual issuer/acquirer from Midtrans response
private String actualIssuerFromMidtrans = ""; private String actualIssuerFromMidtrans = "";
private String actualAcquirerFromMidtrans = ""; private String actualAcquirerFromMidtrans = "";
// ADD: Track QR refresh transaction for payment monitoring // Track QR refresh transaction for payment monitoring
private String currentQrTransactionId = ""; private String currentQrTransactionId = "";
private boolean isMonitoringQrRefreshTransaction = false; private boolean isMonitoringQrRefreshTransaction = false;
@ -97,7 +97,7 @@ public class QrisResultActivity extends AppCompatActivity {
private static final String MIDTRANS_AUTH = "Basic U0ItTWlkLXNlcnZlci1PM2t1bXkwVDl4M1VvYnVvVTc3NW5QbXc="; private static final String MIDTRANS_AUTH = "Basic U0ItTWlkLXNlcnZlci1PM2t1bXkwVDl4M1VvYnVvVTc3NW5QbXc=";
private static final String MIDTRANS_CHARGE_URL = "https://api.sandbox.midtrans.com/v2/charge"; private static final String MIDTRANS_CHARGE_URL = "https://api.sandbox.midtrans.com/v2/charge";
// ADD: Mapping dari technical issuer ke display name // Mapping dari technical issuer ke display name
private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{ private static final Map<String, String> ISSUER_DISPLAY_MAP = new HashMap<String, String>() {{
put("airpay shopee", "ShopeePay"); put("airpay shopee", "ShopeePay");
put("shopeepay", "ShopeePay"); put("shopeepay", "ShopeePay");
@ -125,6 +125,8 @@ public class QrisResultActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// TETAP MENGGUNAKAN LAYOUT ASLI UNTUK QR DISPLAY
setContentView(R.layout.activity_qris_result); setContentView(R.layout.activity_qris_result);
// Initialize views // Initialize views
@ -409,7 +411,7 @@ public class QrisResultActivity extends AppCompatActivity {
} }
} }
// FIXED: Return both QR URL and QR String // ENHANCED: Return both QR URL and QR String
private QrRefreshResult generateNewQrCode() { private QrRefreshResult generateNewQrCode() {
try { try {
Log.d("QrisResultFlow", "🔧 Refreshing QR code for existing transaction"); Log.d("QrisResultFlow", "🔧 Refreshing QR code for existing transaction");
@ -807,7 +809,7 @@ public class QrisResultActivity extends AppCompatActivity {
return fallbackName; return fallbackName;
} }
// COMPLETELY FIXED: Use actual issuer from Midtrans response // ENHANCED: Use actual issuer from Midtrans response
private void syncTransactionStatusToBackend(String finalStatus) { private void syncTransactionStatusToBackend(String finalStatus) {
Log.d("QrisResultFlow", "🔄 Syncing status '" + finalStatus + "' to backend for reference: " + referenceId); Log.d("QrisResultFlow", "🔄 Syncing status '" + finalStatus + "' to backend for reference: " + referenceId);

View File

@ -6,6 +6,8 @@ import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -14,7 +16,6 @@ import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import com.example.bdkipoc.R; import com.example.bdkipoc.R;
import com.google.android.material.button.MaterialButton;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -25,30 +26,39 @@ import java.util.Date;
import java.util.Locale; import java.util.Locale;
/** /**
* ResultTransactionActivity - Enhanced Receipt-style Display with Better Bank Detection * ResultTransactionActivity - Enhanced Receipt-style Display using activity_receipt.xml
* Shows transaction results in a professional receipt format with improved debugging * Shows EMV/Card transaction results using the same layout as QRIS receipts
*/ */
public class ResultTransactionActivity extends AppCompatActivity { public class ResultTransactionActivity extends AppCompatActivity {
private static final String TAG = "ResultTransaction"; private static final String TAG = "ResultTransaction";
// UI Components - New Receipt Layout // UI Components using activity_receipt.xml IDs
private TextView tvMerchantName, tvMerchantLocation;
private TextView tvTid, tvTransactionNumber, tvTransactionDate;
private TextView tvPaymentMethodDetail, tvCardType;
private TextView tvSubtotal, tvTax, tvServiceFee, tvFinalTotal;
private LinearLayout btnPrint, btnEmail;
private MaterialButton btnFinish;
private LinearLayout backNavigation; private LinearLayout backNavigation;
private ImageView backArrow;
private TextView toolbarTitle;
// Hidden compatibility components // Receipt details
private TextView tvAmount, tvStatus, tvReference, tvCardInfo; private TextView merchantName;
private TextView tvPaymentMethod, tvTransactionId, tvOrderId, tvTimestamp; private TextView merchantLocation;
private TextView tvResponseData, tvErrorDetails; private TextView midText;
private LinearLayout layoutErrorDetails; private TextView tidText;
private TextView transactionNumber;
private TextView transactionDate;
private TextView paymentMethod;
private TextView cardType;
private TextView transactionTotal;
private TextView taxPercentage;
private TextView serviceFee;
private TextView finalTotal;
// Action buttons
private LinearLayout printButton;
private LinearLayout emailButton;
private Button finishButton;
// Data from intent // Data from intent
private String transactionAmount; private String transactionAmount;
private String cardType; private String cardTypeFromIntent;
private boolean emvMode; private boolean emvMode;
private String referenceId; private String referenceId;
private String cardNo; private String cardNo;
@ -66,18 +76,21 @@ public class ResultTransactionActivity extends AppCompatActivity {
private long subtotalAmount = 0; private long subtotalAmount = 0;
private long taxAmount = 0; private long taxAmount = 0;
private long serviceFeeAmount = 500; // Default service fee private long serviceFeeAmount = 500; // Default service fee
private double taxPercentage = 0.11; // 11% tax private double taxPercentageValue = 0.11; // 11% tax
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result_transaction);
// CRITICAL: Use the same layout as ReceiptActivity
setContentView(R.layout.activity_receipt);
Log.d(TAG, "=== RESULT TRANSACTION ACTIVITY STARTED ==="); Log.d(TAG, "=== RESULT TRANSACTION ACTIVITY STARTED ===");
Log.d(TAG, "✅ Using activity_receipt.xml layout");
initViews(); initViews();
extractIntentData(); extractIntentData();
debugAllDataSources(); // ENHANCED: Debug all available data debugAllDataSources();
setupListeners(); setupListeners();
calculateAmounts(); calculateAmounts();
displayReceiptData(); displayReceiptData();
@ -86,47 +99,40 @@ public class ResultTransactionActivity extends AppCompatActivity {
} }
private void initViews() { private void initViews() {
// Initialize views using activity_receipt.xml IDs
// Navigation // Navigation
backNavigation = findViewById(R.id.back_navigation); backNavigation = findViewById(R.id.back_navigation);
backArrow = findViewById(R.id.backArrow);
toolbarTitle = findViewById(R.id.toolbarTitle);
// New Receipt Layout Components // Receipt details
tvMerchantName = findViewById(R.id.tv_merchant_name); merchantName = findViewById(R.id.merchant_name);
tvMerchantLocation = findViewById(R.id.tv_merchant_location); merchantLocation = findViewById(R.id.merchant_location);
tvTid = findViewById(R.id.tv_tid); midText = findViewById(R.id.mid_text);
tvTransactionNumber = findViewById(R.id.tv_transaction_number); tidText = findViewById(R.id.tid_text);
tvTransactionDate = findViewById(R.id.tv_transaction_date); transactionNumber = findViewById(R.id.transaction_number);
tvPaymentMethodDetail = findViewById(R.id.tv_payment_method_detail); transactionDate = findViewById(R.id.transaction_date);
tvCardType = findViewById(R.id.tv_card_type); paymentMethod = findViewById(R.id.payment_method);
tvSubtotal = findViewById(R.id.tv_subtotal); cardType = findViewById(R.id.card_type);
tvTax = findViewById(R.id.tv_tax); transactionTotal = findViewById(R.id.transaction_total);
tvServiceFee = findViewById(R.id.tv_service_fee); taxPercentage = findViewById(R.id.tax_percentage);
tvFinalTotal = findViewById(R.id.tv_final_total); serviceFee = findViewById(R.id.service_fee);
finalTotal = findViewById(R.id.final_total);
// Action buttons // Action buttons
btnPrint = findViewById(R.id.btn_print); printButton = findViewById(R.id.print_button);
btnEmail = findViewById(R.id.btn_email); emailButton = findViewById(R.id.email_button);
btnFinish = findViewById(R.id.btn_finish); finishButton = findViewById(R.id.finish_button);
// Hidden compatibility components Log.d(TAG, "✅ All views initialized using activity_receipt.xml");
tvAmount = findViewById(R.id.tv_amount);
tvStatus = findViewById(R.id.tv_status);
tvReference = findViewById(R.id.tv_reference);
tvCardInfo = findViewById(R.id.tv_card_info);
tvPaymentMethod = findViewById(R.id.tv_payment_method);
tvTransactionId = findViewById(R.id.tv_transaction_id);
tvOrderId = findViewById(R.id.tv_order_id);
tvTimestamp = findViewById(R.id.tv_timestamp);
tvResponseData = findViewById(R.id.tv_response_data);
tvErrorDetails = findViewById(R.id.tv_error_details);
layoutErrorDetails = findViewById(R.id.layout_error_details);
} }
// ENHANCED: Better intent data extraction with comprehensive debugging
private void extractIntentData() { private void extractIntentData() {
Intent intent = getIntent(); Intent intent = getIntent();
transactionAmount = intent.getStringExtra("TRANSACTION_AMOUNT"); transactionAmount = intent.getStringExtra("TRANSACTION_AMOUNT");
cardType = intent.getStringExtra("CARD_TYPE"); cardTypeFromIntent = intent.getStringExtra("CARD_TYPE");
emvMode = intent.getBooleanExtra("EMV_MODE", false); emvMode = intent.getBooleanExtra("EMV_MODE", false);
referenceId = intent.getStringExtra("REFERENCE_ID"); referenceId = intent.getStringExtra("REFERENCE_ID");
cardNo = intent.getStringExtra("CARD_NO"); cardNo = intent.getStringExtra("CARD_NO");
@ -136,41 +142,29 @@ public class ResultTransactionActivity extends AppCompatActivity {
emvAid = intent.getStringExtra("EMV_AID"); emvAid = intent.getStringExtra("EMV_AID");
emvExpiry = intent.getStringExtra("EMV_EXPIRY"); emvExpiry = intent.getStringExtra("EMV_EXPIRY");
// ENHANCED: Better debugging for Midtrans response
Log.d(TAG, "=== EXTRACTING INTENT DATA ==="); Log.d(TAG, "=== EXTRACTING INTENT DATA ===");
Log.d(TAG, "Card Type: " + cardType); Log.d(TAG, "Card Type: " + cardTypeFromIntent);
Log.d(TAG, "EMV Mode: " + emvMode); Log.d(TAG, "EMV Mode: " + emvMode);
Log.d(TAG, "Midtrans Response Raw: " + midtransResponse); Log.d(TAG, "Transaction Amount: " + transactionAmount);
Log.d(TAG, "Reference ID: " + referenceId);
Log.d(TAG, "Midtrans Response Length: " + (midtransResponse != null ? midtransResponse.length() : 0)); Log.d(TAG, "Midtrans Response Length: " + (midtransResponse != null ? midtransResponse.length() : 0));
// Parse Midtrans response if available // Parse Midtrans response if available
if (midtransResponse != null && !midtransResponse.isEmpty()) { if (midtransResponse != null && !midtransResponse.isEmpty()) {
try { try {
responseJsonData = new JSONObject(midtransResponse); responseJsonData = new JSONObject(midtransResponse);
// ENHANCED: Debug all fields in response
Log.d(TAG, "✅ Midtrans Response parsed successfully!"); Log.d(TAG, "✅ Midtrans Response parsed successfully!");
Log.d(TAG, "Response keys: " + responseJsonData.keys().toString());
// Check for bank field specifically // Check for bank field specifically
if (responseJsonData.has("bank")) { if (responseJsonData.has("bank")) {
String bankValue = responseJsonData.getString("bank"); String bankValue = responseJsonData.getString("bank");
Log.d(TAG, "✅ Bank field found: '" + bankValue + "' (length: " + bankValue.length() + ")"); Log.d(TAG, "✅ Bank field found: '" + bankValue + "'");
} else { } else {
Log.w(TAG, "⚠️ No 'bank' field in Midtrans response"); Log.w(TAG, "⚠️ No 'bank' field in Midtrans response");
// Check for alternative bank-related fields
String[] possibleBankFields = {"issuer", "card_type", "payment_method", "acquiring_bank"};
for (String field : possibleBankFields) {
if (responseJsonData.has(field)) {
Log.d(TAG, "Alternative field '" + field + "': " + responseJsonData.optString(field));
}
}
} }
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, "❌ Error parsing Midtrans response: " + e.getMessage()); Log.e(TAG, "❌ Error parsing Midtrans response: " + e.getMessage());
Log.e(TAG, "Raw response causing error: " + midtransResponse);
responseJsonData = null; responseJsonData = null;
} }
} else { } else {
@ -181,17 +175,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
Log.d(TAG, "==============================="); Log.d(TAG, "===============================");
} }
private void logTransactionDetails() {
Log.d(TAG, "=== RECEIPT DETAILS ===");
Log.d(TAG, "Reference ID: " + referenceId);
Log.d(TAG, "Card Number: " + (cardNo != null ? maskCardNumber(cardNo) : "N/A"));
Log.d(TAG, "Subtotal: " + subtotalAmount);
Log.d(TAG, "Tax: " + taxAmount);
Log.d(TAG, "Service Fee: " + serviceFeeAmount);
Log.d(TAG, "Final Total: " + (subtotalAmount + taxAmount + serviceFeeAmount));
Log.d(TAG, "======================");
}
private void setupListeners() { private void setupListeners() {
// Back navigation // Back navigation
backNavigation.setOnClickListener(v -> { backNavigation.setOnClickListener(v -> {
@ -199,25 +182,35 @@ public class ResultTransactionActivity extends AppCompatActivity {
navigateBack(); navigateBack();
}); });
backArrow.setOnClickListener(v -> {
if (isNavigating) return;
navigateBack();
});
toolbarTitle.setOnClickListener(v -> {
if (isNavigating) return;
navigateBack();
});
// Print button // Print button
btnPrint.setOnClickListener(v -> { printButton.setOnClickListener(v -> {
showToast("Mencetak struk..."); showToast("Mencetak struk...");
// TODO: Implement print functionality
printReceipt(); printReceipt();
}); });
// Email button // Email button
btnEmail.setOnClickListener(v -> { emailButton.setOnClickListener(v -> {
showToast("Mengirim email..."); showToast("Mengirim email...");
// TODO: Implement email functionality
emailReceipt(); emailReceipt();
}); });
// Finish button // Finish button - Navigate to new transaction
btnFinish.setOnClickListener(v -> { finishButton.setOnClickListener(v -> {
if (isNavigating) return; if (isNavigating) return;
navigateToNewTransaction(); navigateToNewTransaction();
}); });
Log.d(TAG, "✅ All click listeners setup");
} }
private void calculateAmounts() { private void calculateAmounts() {
@ -229,7 +222,7 @@ public class ResultTransactionActivity extends AppCompatActivity {
} }
// Calculate tax (11%) // Calculate tax (11%)
taxAmount = Math.round(subtotalAmount * taxPercentage); taxAmount = Math.round(subtotalAmount * taxPercentageValue);
// Service fee is fixed // Service fee is fixed
serviceFeeAmount = 500; serviceFeeAmount = 500;
@ -247,48 +240,50 @@ public class ResultTransactionActivity extends AppCompatActivity {
} }
private void displayReceiptData() { private void displayReceiptData() {
// ENHANCED: Add debugging at start
Log.d(TAG, "=== DISPLAYING RECEIPT DATA ==="); Log.d(TAG, "=== DISPLAYING RECEIPT DATA ===");
debugAllDataSources(); debugAllDataSources();
// Merchant Information // 1. Set merchant data
tvMerchantName.setText("TOKO KLONTONG PAK EKO"); merchantName.setText("TOKO KLONTONG PAK EKO");
tvMerchantLocation.setText("Ciputat Baru, Tangsel"); merchantLocation.setText("Ciputat Baru, Tangsel");
// Generate or extract transaction details // 2. Set MID and TID
String tid = extractTidFromResponse(); String tid = extractTidFromResponse();
String transactionNumber = extractTransactionNumberFromResponse(); midText.setText("MID: " + tid);
String transactionDate = formatTransactionDate(); tidText.setText("TID: " + tid);
tvTid.setText("TID: " + tid); // 3. Set transaction number
tvTransactionNumber.setText(transactionNumber); String displayTransactionNumber = extractTransactionNumberFromResponse();
tvTransactionDate.setText(transactionDate); transactionNumber.setText(displayTransactionNumber);
// Payment method details // 4. Set transaction date
String paymentMethod = getPaymentMethodDisplay(); String displayDate = formatTransactionDate();
String cardTypeDisplay = getCardTypeDisplay(); transactionDate.setText(displayDate);
// ENHANCED: Add debugging for final values // 5. Set payment method
Log.d(TAG, "Payment Method: " + paymentMethod); String displayPaymentMethod = getPaymentMethodDisplay();
Log.d(TAG, "Final Card Type Display: " + cardTypeDisplay); paymentMethod.setText(displayPaymentMethod);
Log.d(TAG, "================================");
tvPaymentMethodDetail.setText(paymentMethod); // 6. ENHANCED: Set card type with comprehensive detection
tvCardType.setText(cardTypeDisplay); String displayCardType = getCardTypeDisplay();
cardType.setText(displayCardType);
// Amount details // 7. Set amount details
NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID")); NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID"));
tvSubtotal.setText(formatter.format(subtotalAmount)); transactionTotal.setText(formatter.format(subtotalAmount));
tvTax.setText(Math.round(taxPercentage * 100) + "%"); taxPercentage.setText(Math.round(taxPercentageValue * 100) + "%");
tvServiceFee.setText(formatter.format(serviceFeeAmount)); serviceFee.setText(formatter.format(serviceFeeAmount));
// Final total // Final total
long finalTotal = subtotalAmount + taxAmount + serviceFeeAmount; long finalTotalAmount = subtotalAmount + taxAmount + serviceFeeAmount;
tvFinalTotal.setText(formatter.format(finalTotal)); finalTotal.setText(formatter.format(finalTotalAmount));
// Update hidden compatibility components for backward compatibility Log.d(TAG, "✅ Receipt data displayed successfully");
updateCompatibilityComponents(); Log.d(TAG, " Payment Method: " + displayPaymentMethod);
Log.d(TAG, " Card Type: " + displayCardType);
Log.d(TAG, " Final Total: " + formatter.format(finalTotalAmount));
Log.d(TAG, "================================");
} }
private String extractTidFromResponse() { private String extractTidFromResponse() {
@ -331,7 +326,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
try { try {
if (responseJsonData.has("transaction_time")) { if (responseJsonData.has("transaction_time")) {
String transactionTime = responseJsonData.getString("transaction_time"); String transactionTime = responseJsonData.getString("transaction_time");
// Parse and reformat if needed
return formatDateForDisplay(transactionTime); return formatDateForDisplay(transactionTime);
} }
} catch (JSONException e) { } catch (JSONException e) {
@ -345,7 +339,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
private String formatDateForDisplay(String dateString) { private String formatDateForDisplay(String dateString) {
try { try {
// Try to parse the input date string and reformat
SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID")); SimpleDateFormat outputFormat = new SimpleDateFormat("dd MMMM yyyy HH:mm", new Locale("id", "ID"));
Date date = inputFormat.parse(dateString); Date date = inputFormat.parse(dateString);
@ -362,32 +355,31 @@ public class ResultTransactionActivity extends AppCompatActivity {
} }
private String getPaymentMethodDisplay() { private String getPaymentMethodDisplay() {
if (cardType == null) return "Kartu Kredit"; if (cardTypeFromIntent == null) return "Kartu Kredit";
switch (cardType.toUpperCase()) { switch (cardTypeFromIntent.toUpperCase()) {
case "EMV_MIDTRANS": case "EMV_MIDTRANS":
case "IC": case "IC":
case "NFC": case "NFC":
return "Kartu Kredit"; return emvMode ? "Kartu Kredit (EMV)" : "Kartu Kredit";
case "DEBIT": case "DEBIT":
return "Kartu Debit"; return emvMode ? "Kartu Debit (EMV)" : "Kartu Debit";
case "MAGNETIC": case "MAGNETIC":
return "Kartu Magnetic"; return "Kartu Kredit";
default: default:
return "Kartu Kredit"; return "Kartu Kredit";
} }
} }
// ENHANCED: Comprehensive bank detection with multiple fallbacks // ENHANCED: Comprehensive bank detection for EMV transactions
private String getCardTypeDisplay() { private String getCardTypeDisplay() {
Log.d(TAG, "=== DETERMINING CARD TYPE DISPLAY ==="); Log.d(TAG, "=== DETERMINING CARD TYPE DISPLAY (EMV) ===");
// Priority 1: Get bank from Midtrans response (most accurate) // Priority 1: Get bank from Midtrans response (most accurate)
if (responseJsonData != null) { if (responseJsonData != null) {
Log.d(TAG, "✅ Midtrans response available, checking for bank..."); Log.d(TAG, "✅ Midtrans response available, checking for bank...");
try { try {
// ENHANCED: Check multiple possible bank fields
String bankFromResponse = null; String bankFromResponse = null;
if (responseJsonData.has("bank")) { if (responseJsonData.has("bank")) {
@ -405,15 +397,11 @@ public class ResultTransactionActivity extends AppCompatActivity {
String formattedBank = formatBankName(bankFromResponse); String formattedBank = formatBankName(bankFromResponse);
Log.d(TAG, "✅ Bank from Midtrans response: '" + bankFromResponse + "' -> '" + formattedBank + "'"); Log.d(TAG, "✅ Bank from Midtrans response: '" + bankFromResponse + "' -> '" + formattedBank + "'");
return formattedBank; return formattedBank;
} else {
Log.w(TAG, "⚠️ Bank field exists but is empty/null");
} }
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, "❌ Error extracting bank from response: " + e.getMessage()); Log.e(TAG, "❌ Error extracting bank from response: " + e.getMessage());
} }
} else {
Log.w(TAG, "⚠️ No Midtrans response data available");
} }
// Priority 2: EMV AID detection // Priority 2: EMV AID detection
@ -424,9 +412,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
Log.d(TAG, "✅ Bank from EMV AID: " + bankFromAid); Log.d(TAG, "✅ Bank from EMV AID: " + bankFromAid);
return bankFromAid; return bankFromAid;
} }
Log.d(TAG, "EMV AID resulted in default bank");
} else {
Log.d(TAG, "No EMV AID available");
} }
// Priority 3: Card BIN detection // Priority 3: Card BIN detection
@ -436,9 +421,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
String bankFromBin = getBankFromComprehensiveBin(cardBin); String bankFromBin = getBankFromComprehensiveBin(cardBin);
Log.d(TAG, "✅ Bank from BIN (" + cardBin + "): " + bankFromBin); Log.d(TAG, "✅ Bank from BIN (" + cardBin + "): " + bankFromBin);
return bankFromBin; return bankFromBin;
} else {
Log.d(TAG, "Card number too short for BIN detection: " +
(cardNo != null ? cardNo.length() : 0) + " digits");
} }
Log.d(TAG, "⚠️ Using default bank: BCA"); Log.d(TAG, "⚠️ Using default bank: BCA");
@ -446,216 +428,111 @@ public class ResultTransactionActivity extends AppCompatActivity {
return "BCA"; // Default fallback return "BCA"; // Default fallback
} }
// ENHANCED: Better bank name formatting with more variations // ENHANCED: Better bank name formatting
private String formatBankName(String bankName) { private String formatBankName(String bankName) {
if (bankName == null || bankName.trim().isEmpty()) { if (bankName == null || bankName.trim().isEmpty()) {
Log.d(TAG, "Bank name is null/empty, using default BCA");
return "BCA"; // Default return "BCA"; // Default
} }
// Clean and normalize input
String formatted = bankName.trim().toUpperCase(); String formatted = bankName.trim().toUpperCase();
Log.d(TAG, "Formatting bank name: '" + bankName + "' -> '" + formatted + "'");
// Handle common bank name variations // Handle common bank name variations
switch (formatted) { switch (formatted) {
// BCA variations
case "BCA": case "BCA":
case "BANK BCA": case "BANK BCA":
case "BANK CENTRAL ASIA": case "BANK CENTRAL ASIA":
case "PT BANK CENTRAL ASIA TBK":
return "BCA"; return "BCA";
// MANDIRI variations
case "MANDIRI": case "MANDIRI":
case "BANK MANDIRI": case "BANK MANDIRI":
case "PT BANK MANDIRI (PERSERO) TBK": return "Mandiri";
case "MANDIRI BANK":
return "MANDIRI";
// BNI variations
case "BNI": case "BNI":
case "BANK BNI": case "BANK BNI":
case "BANK NEGARA INDONESIA": case "BANK NEGARA INDONESIA":
case "PT BANK NEGARA INDONESIA (PERSERO) TBK":
return "BNI"; return "BNI";
// BRI variations
case "BRI": case "BRI":
case "BANK BRI": case "BANK BRI":
case "BANK RAKYAT INDONESIA": case "BANK RAKYAT INDONESIA":
case "PT BANK RAKYAT INDONESIA (PERSERO) TBK":
return "BRI"; return "BRI";
// CIMB variations
case "CIMB": case "CIMB":
case "CIMB NIAGA": case "CIMB NIAGA":
case "BANK CIMB NIAGA": case "BANK CIMB NIAGA":
case "PT BANK CIMB NIAGA TBK": return "CIMB Niaga";
return "CIMB NIAGA";
// DANAMON variations
case "DANAMON": case "DANAMON":
case "BANK DANAMON": case "BANK DANAMON":
case "PT BANK DANAMON INDONESIA TBK": return "Danamon";
return "DANAMON";
// PERMATA variations
case "PERMATA": case "PERMATA":
case "BANK PERMATA": case "BANK PERMATA":
case "PT BANK PERMATA TBK": return "Permata";
return "PERMATA";
// MEGA variations
case "MEGA":
case "BANK MEGA":
case "PT BANK MEGA TBK":
return "MEGA";
// BTN variations
case "BTN":
case "BANK BTN":
case "BANK TABUNGAN NEGARA":
return "BTN";
// MAYBANK variations
case "MAYBANK":
case "MAYBANK INDONESIA":
case "PT BANK MAYBANK INDONESIA TBK":
return "MAYBANK";
default: default:
// For unknown banks, return as-is but log it return capitalizeFirstLetter(bankName);
Log.d(TAG, "Unknown bank name, returning as-is: " + formatted);
return formatted;
} }
} }
private String getBankFromBin(String bin) {
// Indonesian Bank BIN mapping - return bank names
// BCA
if (bin.startsWith("4621") || bin.startsWith("4699") ||
bin.startsWith("5221") || bin.startsWith("6277")) return "BCA";
// MANDIRI
if (bin.startsWith("4313") || bin.startsWith("5573") ||
bin.startsWith("6011") || bin.startsWith("6234")) return "MANDIRI";
// BNI
if (bin.startsWith("4603") || bin.startsWith("1946") ||
bin.startsWith("5264")) return "BNI";
// BRI
if (bin.startsWith("4578") || bin.startsWith("4479") ||
bin.startsWith("5208")) return "BRI";
// CIMB NIAGA
if (bin.startsWith("4599") || bin.startsWith("5249")) return "CIMB NIAGA";
// DANAMON
if (bin.startsWith("4055") || bin.startsWith("5108")) return "DANAMON";
// Generic fallback based on first digit
if (bin.startsWith("4") || bin.startsWith("5")) {
// Check more specific patterns if needed
return "BCA"; // Default for unknown Visa/Mastercard
}
return "BCA"; // Ultimate fallback
}
private String getBankFromAid(String aid) { private String getBankFromAid(String aid) {
// AID to Indonesian bank mapping // AID to Indonesian bank mapping
// Note: AID identifies card scheme, but we want bank name
// This is best-effort mapping, real bank detection needs BIN
if (aid.contains("A0000000031010")) { if (aid.contains("A0000000031010")) {
// VISA - check if we have card number for better detection // VISA - check if we have card number for better detection
if (cardNo != null && cardNo.length() >= 6) { if (cardNo != null && cardNo.length() >= 6) {
return getBankFromBin(cardNo.substring(0, 6)); return getBankFromComprehensiveBin(cardNo.substring(0, 6));
} }
return "BCA"; // Default for VISA return "BCA"; // Default for VISA
} }
if (aid.contains("A0000000041010")) { if (aid.contains("A0000000041010")) {
// MASTERCARD - check if we have card number for better detection // MASTERCARD
if (cardNo != null && cardNo.length() >= 6) { if (cardNo != null && cardNo.length() >= 6) {
return getBankFromBin(cardNo.substring(0, 6)); return getBankFromComprehensiveBin(cardNo.substring(0, 6));
} }
return "MANDIRI"; // Default for Mastercard return "Mandiri"; // Default for Mastercard
} }
return "BCA"; // Ultimate fallback return "BCA"; // Ultimate fallback
} }
// ENHANCED: More comprehensive Indonesian bank BIN mapping // ENHANCED: Comprehensive Indonesian bank BIN mapping
private String getBankFromComprehensiveBin(String bin) { private String getBankFromComprehensiveBin(String bin) {
if (bin == null || bin.length() < 4) { if (bin == null || bin.length() < 4) {
return "BCA"; // Default return "BCA"; // Default
} }
// More comprehensive Indonesian bank BIN mapping
String bin4 = bin.substring(0, 4); String bin4 = bin.substring(0, 4);
String bin6 = bin.length() >= 6 ? bin.substring(0, 6) : bin4; String bin6 = bin.length() >= 6 ? bin.substring(0, 6) : bin4;
// BCA patterns // BCA patterns
if (bin4.equals("4621") || bin4.equals("4699") || bin4.equals("5221") || bin4.equals("6277") || if (bin4.equals("4621") || bin4.equals("4699") || bin4.equals("5221") || bin4.equals("6277")) {
bin6.startsWith("462117") || bin6.startsWith("469929") || bin6.startsWith("522156")) {
return "BCA"; return "BCA";
} }
// MANDIRI patterns // MANDIRI patterns
if (bin4.equals("4313") || bin4.equals("5573") || bin4.equals("6011") || bin4.equals("6234") || if (bin4.equals("4313") || bin4.equals("5573") || bin4.equals("6011") || bin4.equals("6234")) {
bin4.equals("5406") || bin4.equals("4097") || bin6.startsWith("431360") || bin6.startsWith("557347")) { return "Mandiri";
return "MANDIRI";
} }
// BNI patterns // BNI patterns
if (bin4.equals("4603") || bin4.equals("1946") || bin4.equals("5264") || if (bin4.equals("4603") || bin4.equals("1946") || bin4.equals("5264")) {
bin6.startsWith("460347") || bin6.startsWith("194637") || bin6.startsWith("526435")) {
return "BNI"; return "BNI";
} }
// BRI patterns // BRI patterns
if (bin4.equals("4578") || bin4.equals("4479") || bin4.equals("5208") || bin4.equals("4486") || if (bin4.equals("4578") || bin4.equals("4479") || bin4.equals("5208")) {
bin6.startsWith("457865") || bin6.startsWith("447935") || bin6.startsWith("520834")) {
return "BRI"; return "BRI";
} }
// CIMB NIAGA patterns // CIMB NIAGA patterns
if (bin4.equals("4599") || bin4.equals("5249") || bin4.equals("4543") || if (bin4.equals("4599") || bin4.equals("5249")) {
bin6.startsWith("459923") || bin6.startsWith("524901") || bin6.startsWith("454347")) { return "CIMB Niaga";
return "CIMB NIAGA";
} }
// DANAMON patterns // DANAMON patterns
if (bin4.equals("4055") || bin4.equals("5108") || bin4.equals("4631") || if (bin4.equals("4055") || bin4.equals("5108")) {
bin6.startsWith("405512") || bin6.startsWith("510834") || bin6.startsWith("463178")) { return "Danamon";
return "DANAMON";
}
// PERMATA patterns
if (bin4.equals("5399") || bin4.equals("4723") ||
bin6.startsWith("539923") || bin6.startsWith("472345")) {
return "PERMATA";
}
// MEGA patterns
if (bin4.equals("5221") || bin4.equals("4128") ||
bin6.startsWith("522145") || bin6.startsWith("412834")) {
return "MEGA";
}
// BTN patterns
if (bin4.equals("4058") || bin4.equals("5258") ||
bin6.startsWith("405834") || bin6.startsWith("525823")) {
return "BTN";
}
// MAYBANK patterns
if (bin4.equals("5108") || bin4.equals("4055") ||
bin6.startsWith("510856") || bin6.startsWith("405523")) {
return "MAYBANK";
} }
// Default fallback // Default fallback
@ -663,47 +540,20 @@ public class ResultTransactionActivity extends AppCompatActivity {
return "BCA"; return "BCA";
} }
// Update hidden components for backward compatibility private String capitalizeFirstLetter(String input) {
private void updateCompatibilityComponents() { if (input == null || input.isEmpty()) {
if (tvAmount != null) { return input;
NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID"));
tvAmount.setText("Rp " + formatter.format(subtotalAmount + taxAmount + serviceFeeAmount));
}
if (tvStatus != null) {
tvStatus.setText(paymentSuccess ? "SUCCESS" : "FAILED");
}
if (tvReference != null) {
tvReference.setText(referenceId != null ? referenceId : "N/A");
}
if (tvCardInfo != null) {
tvCardInfo.setText(cardNo != null ? maskCardNumber(cardNo) : "N/A");
}
if (tvPaymentMethod != null) {
tvPaymentMethod.setText(getPaymentMethodDisplay());
}
if (tvTransactionId != null) {
tvTransactionId.setText(extractTransactionNumberFromResponse());
}
if (tvTimestamp != null) {
tvTimestamp.setText(formatTransactionDate());
} }
return input.substring(0, 1).toUpperCase() + input.substring(1).toLowerCase();
} }
// ENHANCED: Add method to debug all data sources // Debug methods
private void debugAllDataSources() { private void debugAllDataSources() {
Log.d(TAG, "=== DEBUGGING ALL DATA SOURCES ==="); Log.d(TAG, "=== DEBUGGING ALL DATA SOURCES ===");
// Check Midtrans response
if (responseJsonData != null) { if (responseJsonData != null) {
Log.d(TAG, "Midtrans Response Available:"); Log.d(TAG, "Midtrans Response Available:");
try { try {
// Log all keys and their values
java.util.Iterator<String> keys = responseJsonData.keys(); java.util.Iterator<String> keys = responseJsonData.keys();
while (keys.hasNext()) { while (keys.hasNext()) {
String key = keys.next(); String key = keys.next();
@ -717,63 +567,35 @@ public class ResultTransactionActivity extends AppCompatActivity {
Log.d(TAG, "❌ No Midtrans Response Data"); Log.d(TAG, "❌ No Midtrans Response Data");
} }
// Check EMV data
Log.d(TAG, "EMV Data:"); Log.d(TAG, "EMV Data:");
Log.d(TAG, " Card Number: " + (cardNo != null ? maskCardNumber(cardNo) : "null")); Log.d(TAG, " Card Number: " + (cardNo != null ? maskCardNumber(cardNo) : "null"));
Log.d(TAG, " EMV AID: " + emvAid); Log.d(TAG, " EMV AID: " + emvAid);
Log.d(TAG, " EMV Cardholder: " + emvCardholderName); Log.d(TAG, " EMV Cardholder: " + emvCardholderName);
Log.d(TAG, " EMV Expiry: " + emvExpiry); Log.d(TAG, " EMV Mode: " + emvMode);
// Check card type
Log.d(TAG, "Card Type: " + cardType);
Log.d(TAG, "EMV Mode: " + emvMode);
Log.d(TAG, "=================================="); Log.d(TAG, "==================================");
} }
// ENHANCED: Method to manually set bank for testing private void logTransactionDetails() {
public void debugSetBank(String bankName) { Log.d(TAG, "=== RECEIPT DETAILS ===");
try { Log.d(TAG, "Reference ID: " + referenceId);
if (responseJsonData == null) { Log.d(TAG, "Card Number: " + (cardNo != null ? maskCardNumber(cardNo) : "N/A"));
responseJsonData = new JSONObject(); Log.d(TAG, "Subtotal: " + subtotalAmount);
} Log.d(TAG, "Tax: " + taxAmount);
responseJsonData.put("bank", bankName); Log.d(TAG, "Service Fee: " + serviceFeeAmount);
Log.d(TAG, "Debug: Manually set bank to: " + bankName); Log.d(TAG, "Final Total: " + (subtotalAmount + taxAmount + serviceFeeAmount));
Log.d(TAG, "======================");
// Refresh display
displayReceiptData();
} catch (JSONException e) {
Log.e(TAG, "Error setting debug bank: " + e.getMessage());
}
}
// ENHANCED: Method to test different bank displays
private void testBankDisplay() {
// Test different bank values
String[] testBanks = {"BCA", "MANDIRI", "BNI", "BRI", "CIMB NIAGA"};
for (String bank : testBanks) {
debugSetBank(bank);
Log.d(TAG, "Test bank '" + bank + "' -> Display: " + getCardTypeDisplay());
}
}
// ENHANCED: Get last response for debugging
public JSONObject getLastMidtransResponse() {
return responseJsonData;
} }
// Action Methods // Action Methods
private void printReceipt() { private void printReceipt() {
Log.d(TAG, "Print receipt requested"); Log.d(TAG, "Print receipt requested");
// TODO: Implement actual printing logic
showToast("Fitur cetak akan segera tersedia"); showToast("Fitur cetak akan segera tersedia");
} }
private void emailReceipt() { private void emailReceipt() {
Log.d(TAG, "Email receipt requested"); Log.d(TAG, "Email receipt requested");
// Create email intent
Intent emailIntent = new Intent(Intent.ACTION_SEND); Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("text/plain"); emailIntent.setType("text/plain");
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Struk Pembayaran - " + extractTransactionNumberFromResponse()); emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Struk Pembayaran - " + extractTransactionNumberFromResponse());
@ -791,9 +613,8 @@ public class ResultTransactionActivity extends AppCompatActivity {
StringBuilder content = new StringBuilder(); StringBuilder content = new StringBuilder();
NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID")); NumberFormat formatter = NumberFormat.getNumberInstance(new Locale("id", "ID"));
content.append("STRUK PEMBAYARAN\n"); content.append("STRUK PEMBAYARAN EMV/CARD\n");
content.append("================\n\n"); content.append("==========================\n\n");
content.append("Payvora PRO\n");
content.append("TOKO KLONTONG PAK EKO\n"); content.append("TOKO KLONTONG PAK EKO\n");
content.append("Ciputat Baru, Tangsel\n\n"); content.append("Ciputat Baru, Tangsel\n\n");
content.append("TID: ").append(extractTidFromResponse()).append("\n"); content.append("TID: ").append(extractTidFromResponse()).append("\n");
@ -801,6 +622,13 @@ public class ResultTransactionActivity extends AppCompatActivity {
content.append("Tanggal: ").append(formatTransactionDate()).append("\n"); content.append("Tanggal: ").append(formatTransactionDate()).append("\n");
content.append("Metode: ").append(getPaymentMethodDisplay()).append("\n"); content.append("Metode: ").append(getPaymentMethodDisplay()).append("\n");
content.append("Jenis Kartu: ").append(getCardTypeDisplay()).append("\n\n"); content.append("Jenis Kartu: ").append(getCardTypeDisplay()).append("\n\n");
if (emvMode && emvCardholderName != null) {
content.append("DETAIL EMV:\n");
content.append("Cardholder: ").append(emvCardholderName).append("\n");
content.append("AID: ").append(emvAid).append("\n\n");
}
content.append("RINCIAN PEMBAYARAN:\n"); content.append("RINCIAN PEMBAYARAN:\n");
content.append("Total Transaksi: Rp ").append(formatter.format(subtotalAmount)).append("\n"); content.append("Total Transaksi: Rp ").append(formatter.format(subtotalAmount)).append("\n");
content.append("Pajak (11%): Rp ").append(formatter.format(taxAmount)).append("\n"); content.append("Pajak (11%): Rp ").append(formatter.format(taxAmount)).append("\n");
@ -824,7 +652,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
private void navigateToNewTransaction() { private void navigateToNewTransaction() {
if (isNavigating) return; if (isNavigating) return;
// Show confirmation dialog
new AlertDialog.Builder(this) new AlertDialog.Builder(this)
.setTitle("Transaksi Baru") .setTitle("Transaksi Baru")
.setMessage("Apakah Anda ingin melakukan transaksi baru?") .setMessage("Apakah Anda ingin melakukan transaksi baru?")
@ -839,7 +666,6 @@ public class ResultTransactionActivity extends AppCompatActivity {
Log.d(TAG, "=== NAVIGATING TO NEW TRANSACTION ==="); Log.d(TAG, "=== NAVIGATING TO NEW TRANSACTION ===");
isNavigating = true; isNavigating = true;
// Add small delay for better UX
new Handler(Looper.getMainLooper()).postDelayed(() -> { new Handler(Looper.getMainLooper()).postDelayed(() -> {
try { try {
Intent intent = new Intent(this, CreateTransactionActivity.class); Intent intent = new Intent(this, CreateTransactionActivity.class);
@ -874,6 +700,7 @@ public class ResultTransactionActivity extends AppCompatActivity {
return; return;
} }
navigateBack(); navigateBack();
super.onBackPressed();
} }
@Override @Override

View File

@ -104,7 +104,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="EDC " android:text="Payvora "
android:textColor="#E31937" android:textColor="#E31937"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
@ -113,7 +113,7 @@
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Merchant" android:text="PRO"
android:textColor="#3F51B5" android:textColor="#3F51B5"
android:textSize="24sp" android:textSize="24sp"
android:textStyle="bold" android:textStyle="bold"
@ -121,15 +121,6 @@
</LinearLayout> </LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="BANK BRI"
android:textColor="#333333"
android:textSize="12sp"
android:fontFamily="@font/inter"
android:layout_marginTop="2dp"/>
</LinearLayout> </LinearLayout>
<!-- Merchant Info --> <!-- Merchant Info -->
@ -168,46 +159,36 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center"
android:layout_marginBottom="8dp"> android:layout_marginBottom="8dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="MID: "
android:textColor="#666666"
android:textSize="12sp"
android:fontFamily="@font/inter"/>
<TextView <TextView
android:id="@+id/mid_text" android:id="@+id/mid_text"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:text="MID:12345678901"
android:text="1234567890"
android:textColor="#333333" android:textColor="#333333"
android:textSize="12sp" android:textSize="12sp"
android:fontFamily="@font/inter"/> android:fontFamily="@font/inter"/>
<!-- Vertical Separator -->
<TextView <TextView
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:text=" | "
android:text="TID: " android:textColor="#999999"
android:textColor="#666666"
android:textSize="12sp" android:textSize="12sp"
android:fontFamily="@font/inter"/> android:fontFamily="@font/inter"
android:paddingHorizontal="8dp"/>
<TextView <TextView
android:id="@+id/tid_text" android:id="@+id/tid_text"
android:layout_width="0dp" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="1" android:text="TID:12345678901"
android:text="1234567890"
android:textColor="#333333" android:textColor="#333333"
android:textSize="12sp" android:textSize="12sp"
android:fontFamily="@font/inter"/> android:fontFamily="@font/inter"/>
</LinearLayout> </LinearLayout>
<!-- Separator Line --> <!-- Separator Line -->