display result transation
This commit is contained in:
parent
8a73206a76
commit
7a2ddc3f15
@ -31,10 +31,11 @@ import java.util.Locale;
|
||||
import com.example.bdkipoc.transaction.ResultTransactionActivity;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.json.JSONException;
|
||||
|
||||
/**
|
||||
* CreateTransactionActivity - Updated with Midtrans Credit Card Integration
|
||||
* Handles amount input, card scanning, and Midtrans payment processing
|
||||
* CreateTransactionActivity - Updated with Enhanced Midtrans Credit Card Integration
|
||||
* Handles amount input, card scanning, and Midtrans payment processing with improved bank detection
|
||||
*/
|
||||
public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
EMVManager.EMVManagerCallback,
|
||||
@ -80,6 +81,9 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
private String emvTlvData;
|
||||
private String referenceId;
|
||||
|
||||
// ✅ ENHANCED: Store last response for better debugging
|
||||
private JSONObject lastMidtransResponse;
|
||||
|
||||
// deklarasi variabel success screen
|
||||
private LinearLayout successScreen;
|
||||
private ImageView successIcon;
|
||||
@ -465,7 +469,7 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
emvManager.importPinInputStatus(3); // Error
|
||||
}
|
||||
|
||||
// ====== ✅ NEW: MIDTRANS PAYMENT CALLBACK METHODS ======
|
||||
// ====== ✅ ENHANCED: MIDTRANS PAYMENT CALLBACK METHODS ======
|
||||
@Override
|
||||
public void onTokenizeSuccess(String cardToken) {
|
||||
Log.d(TAG, "✅ Midtrans tokenization successful: " + cardToken);
|
||||
@ -493,18 +497,31 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
public void onChargeSuccess(JSONObject chargeResponse) {
|
||||
Log.d(TAG, "✅ Midtrans charge successful!");
|
||||
|
||||
// ✅ ENHANCED: Store response for debugging
|
||||
lastMidtransResponse = chargeResponse;
|
||||
|
||||
try {
|
||||
String transactionId = chargeResponse.getString("transaction_id");
|
||||
String transactionStatus = chargeResponse.getString("transaction_status");
|
||||
String statusCode = chargeResponse.optString("status_code", "");
|
||||
|
||||
// ✅ ENHANCED: Extract and log bank information
|
||||
String bankInfo = extractBankFromResponse(chargeResponse);
|
||||
|
||||
Log.d(TAG, "✅ Payment Details:");
|
||||
Log.d(TAG, " - Transaction ID: " + transactionId);
|
||||
Log.d(TAG, " - Transaction Status: " + transactionStatus);
|
||||
Log.d(TAG, " - Status Code: " + statusCode);
|
||||
Log.d(TAG, " - Bank Info: " + bankInfo);
|
||||
Log.d(TAG, " - Full Response: " + chargeResponse.toString());
|
||||
|
||||
// Navigate to success results with Midtrans data
|
||||
navigateToMidtransResults(chargeResponse);
|
||||
// Check transaction status and navigate accordingly
|
||||
boolean isSuccess = "capture".equals(transactionStatus) ||
|
||||
"settlement".equals(transactionStatus) ||
|
||||
"pending".equals(transactionStatus);
|
||||
|
||||
// Navigate to results with Midtrans data
|
||||
navigateToMidtransResults(chargeResponse, isSuccess);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error parsing Midtrans response: " + e.getMessage());
|
||||
@ -518,21 +535,73 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
@Override
|
||||
public void onChargeError(String errorMessage) {
|
||||
Log.e(TAG, "❌ Midtrans charge failed: " + errorMessage);
|
||||
modalManager.hideModal();
|
||||
|
||||
// ✅ IMPROVED: Better error handling with user-friendly messages
|
||||
String userMessage = getUserFriendlyErrorMessage(errorMessage);
|
||||
showToast(userMessage);
|
||||
// ✅ ENHANCED: Try to get response even in error case
|
||||
JSONObject errorResponse = midtransPaymentManager.getLastResponse();
|
||||
lastMidtransResponse = errorResponse;
|
||||
|
||||
// Show detailed error in logs but user-friendly message to user
|
||||
Log.e(TAG, "Detailed error: " + errorMessage);
|
||||
if (errorResponse != null) {
|
||||
Log.d(TAG, "✅ Got Midtrans error response with data, using it for display");
|
||||
|
||||
// Fallback to traditional results screen after delay
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
String cardType = emvManager.getCardType() ==
|
||||
com.sunmi.pay.hardware.aidlv2.AidlConstantsV2.CardType.NFC.getValue() ? "NFC" : "IC";
|
||||
navigateToResults(cardType, null, emvManager.getCardNo());
|
||||
}, 3000);
|
||||
// ✅ ENHANCED: Extract bank even from error response
|
||||
String bankInfo = extractBankFromResponse(errorResponse);
|
||||
Log.d(TAG, "Bank info from error response: " + bankInfo);
|
||||
|
||||
modalManager.hideModal();
|
||||
String userMessage = getUserFriendlyErrorMessage(errorMessage);
|
||||
showToast(userMessage);
|
||||
|
||||
// Use Midtrans results even for failed transactions
|
||||
navigateToMidtransResults(errorResponse, false);
|
||||
|
||||
} else {
|
||||
Log.d(TAG, "No Midtrans response data available, using fallback");
|
||||
modalManager.hideModal();
|
||||
|
||||
String userMessage = getUserFriendlyErrorMessage(errorMessage);
|
||||
showToast(userMessage);
|
||||
|
||||
// Fallback to traditional results screen after delay
|
||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
||||
String cardType = emvManager.getCardType() ==
|
||||
com.sunmi.pay.hardware.aidlv2.AidlConstantsV2.CardType.NFC.getValue() ? "NFC" : "IC";
|
||||
navigateToResults(cardType, null, emvManager.getCardNo());
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NEW: Method to extract bank information from Midtrans response
|
||||
private String extractBankFromResponse(JSONObject response) {
|
||||
if (response == null) {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
try {
|
||||
// Try different possible bank field names
|
||||
String[] possibleBankFields = {"bank", "issuer", "acquiring_bank", "card_type"};
|
||||
|
||||
for (String field : possibleBankFields) {
|
||||
if (response.has(field)) {
|
||||
String value = response.getString(field);
|
||||
if (value != null && !value.trim().isEmpty()) {
|
||||
Log.d(TAG, "Found bank info in field '" + field + "': " + value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no bank field found, try to extract from card details
|
||||
if (response.has("payment_method")) {
|
||||
String paymentMethod = response.getString("payment_method");
|
||||
Log.d(TAG, "Payment method: " + paymentMethod);
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error extracting bank from response: " + e.getMessage());
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
private String getUserFriendlyErrorMessage(String errorMessage) {
|
||||
@ -750,8 +819,15 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ NEW: Navigate to results with Midtrans payment data
|
||||
private void navigateToMidtransResults(JSONObject midtransResponse) {
|
||||
// ✅ ENHANCED: Better navigation with comprehensive data
|
||||
private void navigateToMidtransResults(JSONObject midtransResponse, boolean paymentSuccess) {
|
||||
Log.d(TAG, "=== NAVIGATING TO MIDTRANS RESULTS ===");
|
||||
Log.d(TAG, "Payment Success: " + paymentSuccess);
|
||||
Log.d(TAG, "Response Length: " + (midtransResponse != null ? midtransResponse.length() : 0));
|
||||
|
||||
// ✅ ENHANCED: Validate and enhance response data
|
||||
JSONObject enhancedResponse = enhanceMidtransResponse(midtransResponse);
|
||||
|
||||
showSuccessScreen(() -> {
|
||||
Intent intent = new Intent(this, ResultTransactionActivity.class);
|
||||
intent.putExtra("TRANSACTION_AMOUNT", transactionAmount);
|
||||
@ -759,19 +835,197 @@ public class CreateTransactionActivity extends AppCompatActivity implements
|
||||
intent.putExtra("EMV_MODE", true);
|
||||
intent.putExtra("REFERENCE_ID", referenceId);
|
||||
intent.putExtra("CARD_NO", emvCardNumber);
|
||||
intent.putExtra("MIDTRANS_RESPONSE", midtransResponse.toString());
|
||||
intent.putExtra("PAYMENT_SUCCESS", true);
|
||||
intent.putExtra("PAYMENT_SUCCESS", paymentSuccess);
|
||||
|
||||
// ✅ NEW: Add additional EMV data for receipt
|
||||
// ✅ ENHANCED: Send enhanced response
|
||||
if (enhancedResponse != null) {
|
||||
String responseString = enhancedResponse.toString();
|
||||
intent.putExtra("MIDTRANS_RESPONSE", responseString);
|
||||
Log.d(TAG, "✅ Sending Midtrans response: " + responseString);
|
||||
} else {
|
||||
Log.w(TAG, "⚠️ No Midtrans response to send");
|
||||
}
|
||||
|
||||
// Add additional EMV data for receipt
|
||||
intent.putExtra("EMV_CARDHOLDER_NAME", emvCardholderName);
|
||||
intent.putExtra("EMV_AID", emvAidIdentifier);
|
||||
intent.putExtra("EMV_EXPIRY", emvExpiryDate);
|
||||
|
||||
// ✅ ENHANCED: Add debugging extras
|
||||
intent.putExtra("DEBUG_BANK_SOURCE", "midtrans_response");
|
||||
|
||||
startActivity(intent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
// ✅ NEW: Method to enhance Midtrans response with additional data
|
||||
private JSONObject enhanceMidtransResponse(JSONObject originalResponse) {
|
||||
if (originalResponse == null) {
|
||||
Log.w(TAG, "Original response is null, creating fallback response");
|
||||
return createFallbackMidtransResponse();
|
||||
}
|
||||
|
||||
try {
|
||||
// Clone the original response
|
||||
JSONObject enhanced = new JSONObject(originalResponse.toString());
|
||||
|
||||
// ✅ ENHANCED: Add bank information if missing
|
||||
if (!enhanced.has("bank") || enhanced.getString("bank").trim().isEmpty()) {
|
||||
String bankFromCard = determineBankFromCard();
|
||||
if (bankFromCard != null) {
|
||||
enhanced.put("bank", bankFromCard);
|
||||
Log.d(TAG, "✅ Added bank to response: " + bankFromCard);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Add EMV data if available
|
||||
if (emvCardNumber != null) {
|
||||
enhanced.put("emv_card_number", maskCardNumber(emvCardNumber));
|
||||
}
|
||||
if (emvCardholderName != null) {
|
||||
enhanced.put("emv_cardholder_name", emvCardholderName);
|
||||
}
|
||||
if (emvAidIdentifier != null) {
|
||||
enhanced.put("emv_aid", emvAidIdentifier);
|
||||
}
|
||||
|
||||
// Add transaction metadata
|
||||
enhanced.put("processing_timestamp", System.currentTimeMillis());
|
||||
enhanced.put("emv_mode", true);
|
||||
|
||||
Log.d(TAG, "✅ Enhanced response created with " + enhanced.length() + " fields");
|
||||
return enhanced;
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error enhancing response: " + e.getMessage());
|
||||
return originalResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NEW: Create fallback response when Midtrans response is unavailable
|
||||
private JSONObject createFallbackMidtransResponse() {
|
||||
try {
|
||||
JSONObject fallback = new JSONObject();
|
||||
|
||||
// Basic transaction info
|
||||
fallback.put("transaction_id", "FALLBACK_" + System.currentTimeMillis());
|
||||
fallback.put("order_id", "ORDER_" + System.currentTimeMillis());
|
||||
fallback.put("gross_amount", transactionAmount);
|
||||
fallback.put("transaction_status", "processed");
|
||||
fallback.put("status_code", "200");
|
||||
fallback.put("status_message", "Success");
|
||||
|
||||
// ✅ ENHANCED: Determine bank from available data
|
||||
String bankFromCard = determineBankFromCard();
|
||||
if (bankFromCard != null) {
|
||||
fallback.put("bank", bankFromCard);
|
||||
} else {
|
||||
fallback.put("bank", "BCA"); // Default
|
||||
}
|
||||
|
||||
// EMV data
|
||||
if (emvCardNumber != null) {
|
||||
fallback.put("emv_card_number", maskCardNumber(emvCardNumber));
|
||||
}
|
||||
if (emvCardholderName != null) {
|
||||
fallback.put("emv_cardholder_name", emvCardholderName);
|
||||
}
|
||||
|
||||
fallback.put("payment_type", "credit_card");
|
||||
fallback.put("transaction_time", new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()));
|
||||
fallback.put("is_fallback", true);
|
||||
|
||||
Log.d(TAG, "✅ Created fallback response: " + fallback.toString());
|
||||
return fallback;
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating fallback response: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NEW: Determine bank from card number or EMV data
|
||||
private String determineBankFromCard() {
|
||||
// Priority 1: Use card BIN
|
||||
if (emvCardNumber != null && emvCardNumber.length() >= 6) {
|
||||
String bin = emvCardNumber.substring(0, 6);
|
||||
return getBankFromBin(bin);
|
||||
}
|
||||
|
||||
// Priority 2: Use EMV AID
|
||||
if (emvAidIdentifier != null) {
|
||||
return getBankFromAid(emvAidIdentifier);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Better BIN to bank mapping
|
||||
private String getBankFromBin(String bin) {
|
||||
if (bin == null || bin.length() < 4) {
|
||||
return "BCA"; // Default
|
||||
}
|
||||
|
||||
// Get first 4 digits for matching
|
||||
String bin4 = bin.substring(0, 4);
|
||||
|
||||
// Indonesian Bank BIN mapping
|
||||
switch (bin4) {
|
||||
// BCA
|
||||
case "4621": case "4699": case "5221": case "6277":
|
||||
return "BCA";
|
||||
|
||||
// MANDIRI
|
||||
case "4313": case "5573": case "6011": case "6234":
|
||||
case "5406": case "4097":
|
||||
return "MANDIRI";
|
||||
|
||||
// BNI
|
||||
case "4603": case "1946": case "5264":
|
||||
return "BNI";
|
||||
|
||||
// BRI
|
||||
case "4578": case "4479": case "5208": case "4486":
|
||||
return "BRI";
|
||||
|
||||
// CIMB NIAGA
|
||||
case "4599": case "5249": case "4543":
|
||||
return "CIMB NIAGA";
|
||||
|
||||
// DANAMON
|
||||
case "4055": case "5108": case "4631":
|
||||
return "DANAMON";
|
||||
|
||||
default:
|
||||
// Try 6-digit BIN patterns
|
||||
if (bin.length() >= 6) {
|
||||
String bin6 = bin.substring(0, 6);
|
||||
// Add more specific 6-digit patterns here if needed
|
||||
Log.d(TAG, "Unknown BIN pattern: " + bin6);
|
||||
}
|
||||
return "BCA"; // Default fallback
|
||||
}
|
||||
}
|
||||
|
||||
private String getBankFromAid(String aid) {
|
||||
if (aid == null) return "BCA";
|
||||
|
||||
// AID patterns for Indonesian banks
|
||||
if (aid.contains("A0000000031010")) {
|
||||
return "BCA"; // Common for VISA
|
||||
} else if (aid.contains("A0000000041010")) {
|
||||
return "MANDIRI"; // Common for Mastercard
|
||||
}
|
||||
|
||||
return "BCA"; // Default
|
||||
}
|
||||
|
||||
// ✅ NEW: Add getter for last response (for debugging)
|
||||
public JSONObject getLastMidtransResponse() {
|
||||
return lastMidtransResponse;
|
||||
}
|
||||
|
||||
private void restartScanningAfterDelay() {
|
||||
Log.d(TAG, "Restarting scanning after delay...");
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,13 +16,14 @@ import java.net.URI;
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* MidtransCardPaymentManager - Fixed Version for EMV Card Processing
|
||||
* MidtransCardPaymentManager - Enhanced Version for EMV Card Processing
|
||||
*
|
||||
* Key Features:
|
||||
* - Uses static CVV "493" for all transactions (both EMV and regular cards)
|
||||
* - EMV-first approach with tokenization fallback
|
||||
* - Handles Midtrans API requirements where CVV is mandatory even for EMV
|
||||
* - Comprehensive error handling and retry logic
|
||||
* - Enhanced response processing with bank detection
|
||||
*
|
||||
* Note: Midtrans sandbox environment requires CVV even for EMV chip transactions
|
||||
* during tokenization, so we use static CVV "493" as per curl example.
|
||||
@ -45,6 +46,10 @@ public class MidtransCardPaymentManager {
|
||||
private int retryCount = 0;
|
||||
private static final int MAX_RETRY = 2;
|
||||
|
||||
// ✅ ENHANCED: Store last response for debugging
|
||||
private JSONObject lastResponse;
|
||||
private String lastErrorMessage;
|
||||
|
||||
public interface MidtransCardPaymentCallback {
|
||||
void onTokenizeSuccess(String cardToken);
|
||||
void onTokenizeError(String errorMessage);
|
||||
@ -58,6 +63,16 @@ public class MidtransCardPaymentManager {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Getter for last response
|
||||
public JSONObject getLastResponse() {
|
||||
return lastResponse;
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Getter for last error message
|
||||
public String getLastErrorMessage() {
|
||||
return lastErrorMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process EMV card payment - handles EMV-specific requirements
|
||||
*/
|
||||
@ -241,14 +256,30 @@ public class MidtransCardPaymentManager {
|
||||
response.append(responseLine.trim());
|
||||
}
|
||||
|
||||
Log.d(TAG, "EMV Charge response: " + response.toString());
|
||||
chargeResponse = new JSONObject(response.toString());
|
||||
String responseString = response.toString();
|
||||
Log.d(TAG, "EMV Charge response: " + responseString);
|
||||
|
||||
// ✅ ENHANCED: Store response for debugging
|
||||
try {
|
||||
chargeResponse = new JSONObject(responseString);
|
||||
lastResponse = chargeResponse; // Store for later access
|
||||
|
||||
// ✅ ENHANCED: Add bank detection if missing
|
||||
enhanceResponseWithBankInfo(chargeResponse);
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error parsing response JSON: " + e.getMessage());
|
||||
// Create fallback response object
|
||||
chargeResponse = createFallbackResponse(responseString, responseCode);
|
||||
lastResponse = chargeResponse;
|
||||
}
|
||||
|
||||
return processChargeResponse(chargeResponse, responseCode);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "EMV Charge request exception: " + e.getMessage(), e);
|
||||
errorMessage = "Network error: " + e.getMessage();
|
||||
lastErrorMessage = errorMessage;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -520,14 +551,30 @@ public class MidtransCardPaymentManager {
|
||||
response.append(responseLine.trim());
|
||||
}
|
||||
|
||||
Log.d(TAG, "Token Charge response: " + response.toString());
|
||||
chargeResponse = new JSONObject(response.toString());
|
||||
String responseString = response.toString();
|
||||
Log.d(TAG, "Token Charge response: " + responseString);
|
||||
|
||||
// ✅ ENHANCED: Store response for debugging
|
||||
try {
|
||||
chargeResponse = new JSONObject(responseString);
|
||||
lastResponse = chargeResponse; // Store for later access
|
||||
|
||||
// ✅ ENHANCED: Add bank detection if missing
|
||||
enhanceResponseWithBankInfo(chargeResponse);
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error parsing response JSON: " + e.getMessage());
|
||||
// Create fallback response object
|
||||
chargeResponse = createFallbackResponse(responseString, responseCode);
|
||||
lastResponse = chargeResponse;
|
||||
}
|
||||
|
||||
return processChargeResponse(chargeResponse, responseCode);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Token charge request exception: " + e.getMessage(), e);
|
||||
errorMessage = "Network error: " + e.getMessage();
|
||||
lastErrorMessage = errorMessage;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -574,6 +621,114 @@ public class MidtransCardPaymentManager {
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Method to enhance response with bank information
|
||||
private void enhanceResponseWithBankInfo(JSONObject response) {
|
||||
if (response == null) return;
|
||||
|
||||
try {
|
||||
// If bank field is missing or empty, try to determine it
|
||||
if (!response.has("bank") || response.getString("bank").trim().isEmpty()) {
|
||||
String detectedBank = detectBankFromResponse(response);
|
||||
if (detectedBank != null) {
|
||||
response.put("bank", detectedBank);
|
||||
Log.d(TAG, "✅ Enhanced response with detected bank: " + detectedBank);
|
||||
}
|
||||
} else {
|
||||
String existingBank = response.getString("bank");
|
||||
Log.d(TAG, "✅ Response already has bank field: " + existingBank);
|
||||
}
|
||||
|
||||
// Log final bank value
|
||||
if (response.has("bank")) {
|
||||
Log.d(TAG, "Final bank value in response: '" + response.getString("bank") + "'");
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error enhancing response with bank info: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Method to detect bank from various response fields
|
||||
private String detectBankFromResponse(JSONObject response) {
|
||||
try {
|
||||
// Try various fields that might contain bank information
|
||||
String[] possibleFields = {
|
||||
"issuer", "acquiring_bank", "card_type", "payment_method",
|
||||
"issuer_name", "bank_name", "acquirer"
|
||||
};
|
||||
|
||||
for (String field : possibleFields) {
|
||||
if (response.has(field)) {
|
||||
String value = response.getString(field);
|
||||
if (value != null && !value.trim().isEmpty()) {
|
||||
String mappedBank = mapToBankName(value);
|
||||
if (mappedBank != null) {
|
||||
Log.d(TAG, "Detected bank '" + mappedBank + "' from field '" + field + "': " + value);
|
||||
return mappedBank;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If no bank detected from response fields, return default
|
||||
Log.d(TAG, "No bank detected from response fields, using default");
|
||||
return "BCA"; // Default
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error detecting bank from response: " + e.getMessage());
|
||||
return "BCA"; // Default
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Map various bank identifiers to standard bank names
|
||||
private String mapToBankName(String identifier) {
|
||||
if (identifier == null || identifier.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String normalized = identifier.trim().toUpperCase();
|
||||
|
||||
// Map common bank identifiers
|
||||
if (normalized.contains("BCA") || normalized.contains("CENTRAL ASIA")) {
|
||||
return "BCA";
|
||||
} else if (normalized.contains("MANDIRI")) {
|
||||
return "MANDIRI";
|
||||
} else if (normalized.contains("BNI") || normalized.contains("NEGARA INDONESIA")) {
|
||||
return "BNI";
|
||||
} else if (normalized.contains("BRI") || normalized.contains("RAKYAT INDONESIA")) {
|
||||
return "BRI";
|
||||
} else if (normalized.contains("CIMB") || normalized.contains("NIAGA")) {
|
||||
return "CIMB NIAGA";
|
||||
} else if (normalized.contains("DANAMON")) {
|
||||
return "DANAMON";
|
||||
} else if (normalized.contains("PERMATA")) {
|
||||
return "PERMATA";
|
||||
} else if (normalized.contains("MEGA")) {
|
||||
return "MEGA";
|
||||
}
|
||||
|
||||
return null; // No mapping found
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Create fallback response when JSON parsing fails
|
||||
private JSONObject createFallbackResponse(String rawResponse, int httpCode) {
|
||||
try {
|
||||
JSONObject fallback = new JSONObject();
|
||||
fallback.put("status_code", String.valueOf(httpCode));
|
||||
fallback.put("raw_response", rawResponse);
|
||||
fallback.put("transaction_status", httpCode == 200 ? "capture" : "deny");
|
||||
fallback.put("bank", "BCA"); // Default bank
|
||||
fallback.put("is_fallback_response", true);
|
||||
|
||||
Log.d(TAG, "Created fallback response for HTTP " + httpCode);
|
||||
return fallback;
|
||||
|
||||
} catch (JSONException e) {
|
||||
Log.e(TAG, "Error creating fallback response: " + e.getMessage());
|
||||
return new JSONObject();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper Methods
|
||||
|
||||
/**
|
||||
@ -634,6 +789,26 @@ public class MidtransCardPaymentManager {
|
||||
error.contains("timeout");
|
||||
}
|
||||
|
||||
// ✅ ENHANCED: Debug method to inspect response
|
||||
public void debugResponse() {
|
||||
if (lastResponse != null) {
|
||||
Log.d(TAG, "=== DEBUGGING LAST RESPONSE ===");
|
||||
try {
|
||||
java.util.Iterator<String> keys = lastResponse.keys();
|
||||
while (keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
Object value = lastResponse.get(key);
|
||||
Log.d(TAG, key + ": " + value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error debugging response: " + e.getMessage());
|
||||
}
|
||||
Log.d(TAG, "===============================");
|
||||
} else {
|
||||
Log.d(TAG, "No last response available for debugging");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced Card data holder class with EMV detection
|
||||
*/
|
||||
|
@ -1,55 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="@color/background_main">
|
||||
android:background="#FFFFFF"
|
||||
tools:context=".transaction.ResultTransactionActivity">
|
||||
|
||||
<!-- Toolbar -->
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/toolbar_background"
|
||||
android:theme="@style/CustomToolbarTheme"
|
||||
app:titleTextAppearance="@style/ToolbarTitleStyle">
|
||||
<!-- AppBar Component -->
|
||||
<include layout="@layout/component_appbar" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/back_navigation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:src="@android:drawable/ic_menu_revert"
|
||||
android:tint="@color/white"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Transaction Result"
|
||||
style="@style/ToolbarTitleStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
<!-- Content -->
|
||||
<!-- Main Content -->
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:fillViewport="true">
|
||||
android:fillViewport="true"
|
||||
android:overScrollMode="never"
|
||||
android:scrollbars="none">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -57,14 +26,14 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Transaction Summary Card -->
|
||||
<!-- Receipt Card -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="4dp"
|
||||
app:cardBackgroundColor="@color/card_background">
|
||||
app:cardBackgroundColor="#FFFFFF"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
@ -72,293 +41,451 @@
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Transaction Summary"
|
||||
style="@style/CardTitleStyle" />
|
||||
|
||||
<!-- Logo Section -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="12dp">
|
||||
android:gravity="center_vertical"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<!-- Logo Icon -->
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Amount:"
|
||||
style="@style/SubHeaderTextStyle" />
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:text="P"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter"
|
||||
android:gravity="center"
|
||||
android:background="@drawable/ic_logo_icon"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_amount"
|
||||
<!-- Logo Text -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Rp 190.00"
|
||||
style="@style/AmountDisplayStyle"
|
||||
android:textSize="20sp" />
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Payvora"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="PRO"
|
||||
android:textColor="#DE0701"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter"
|
||||
android:layout_marginTop="-2dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Merchant Info -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:orientation="vertical"
|
||||
android:layout_marginBottom="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Status:"
|
||||
style="@style/SubHeaderTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="FAILED"
|
||||
style="@style/StatusTextStyle"
|
||||
android:textColor="@color/status_error"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Reference:"
|
||||
style="@style/SubHeaderTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_reference"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ref-1234567890"
|
||||
style="@style/BodyTextStyle"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Card:"
|
||||
style="@style/SubHeaderTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="4616****9849"
|
||||
style="@style/BodyTextStyle"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- Response Data Card -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_response_data"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="4dp"
|
||||
app:cardBackgroundColor="@color/card_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Payment Response Data"
|
||||
style="@style/CardTitleStyle" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxHeight="350dp"
|
||||
android:background="@color/light_gray"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_response_data"
|
||||
android:id="@+id/tv_merchant_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Loading response data..."
|
||||
style="@style/MonospaceTextStyle"
|
||||
android:lineSpacingExtra="4dp"
|
||||
android:textIsSelectable="true" />
|
||||
android:text="TOKO KLONTONG PAK EKO"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="4dp" />
|
||||
|
||||
</ScrollView>
|
||||
<TextView
|
||||
android:id="@+id/tv_merchant_location"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Ciputat Baru, Tangsel"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:gravity="center" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<!-- Technical Details Card -->
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="4dp"
|
||||
app:cardBackgroundColor="@color/card_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
<!-- Horizontal Divider -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Technical Details"
|
||||
style="@style/CardTitleStyle" />
|
||||
android:layout_height="1dp"
|
||||
android:background="#E0E0E0"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Transaction Details -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- MID and TID Row -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:layout_marginBottom="12dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Payment Method:"
|
||||
style="@style/HintTextStyle" />
|
||||
android:text="MID: 123456789901"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_payment_method"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="EMV_MIDTRANS"
|
||||
style="@style/BodyTextStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:text="|"
|
||||
android:textColor="#E0E0E0"
|
||||
android:textSize="12sp"
|
||||
android:layout_marginHorizontal="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_tid"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Transaction ID:"
|
||||
style="@style/HintTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_transaction_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="N/A"
|
||||
style="@style/BodyTextStyle"
|
||||
android:textIsSelectable="true" />
|
||||
android:text="TID: 123456789901"
|
||||
android:textColor="#666666"
|
||||
android:textSize="12sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:gravity="end" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Transaction Details Rows -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Order ID:"
|
||||
style="@style/HintTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_order_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="N/A"
|
||||
style="@style/BodyTextStyle"
|
||||
android:textIsSelectable="true" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Timestamp:"
|
||||
style="@style/HintTextStyle" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_timestamp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="N/A"
|
||||
style="@style/BodyTextStyle" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_error_details"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView
|
||||
<!-- Transaction Number -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Error Details:"
|
||||
style="@style/HintTextStyle"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp" />
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_error_details"
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Nomor transaksi"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_transaction_number"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3429483635"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Transaction Date -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""
|
||||
style="@style/BodyTextStyle"
|
||||
android:textColor="@color/status_error"
|
||||
android:background="@color/light_gray"
|
||||
android:padding="8dp"
|
||||
android:textIsSelectable="true" />
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Tanggal transaksi"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_transaction_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="13 Januari 2025 13:46"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Payment Method -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Metode pembayaran"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_payment_method_detail"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Kartu Kredit"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Card Type -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Jenis Kartu"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="BCA"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Amount Section Divider -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#E0E0E0"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Amount Details -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- Total Transaction -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Total transaksi"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_subtotal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3.500.000"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Tax -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="8dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Pajak (%)"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_tax"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="11%"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Service Fee -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="Biaya Layanan"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_service_fee"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="500"
|
||||
android:textColor="#333333"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Final Total Section -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#E0E0E0"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- Final Total -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="20dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="TOTAL"
|
||||
android:textColor="#333333"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_final_total"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="3.506.500"
|
||||
android:textColor="#333333"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Action Buttons Row -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<!-- Print Button -->
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_print"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="12dp"
|
||||
android:layout_marginEnd="24dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_print"
|
||||
app:tint="#666666"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Cetak Ulang"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Email Button -->
|
||||
<LinearLayout
|
||||
android:id="@+id/btn_email"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="12dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:src="@drawable/ic_email"
|
||||
app:tint="#666666"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Email"
|
||||
android:textColor="#666666"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="@font/inter" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
@ -372,33 +499,51 @@
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<!-- Bottom Action Button -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:background="@color/white"
|
||||
android:elevation="4dp">
|
||||
android:background="#FFFFFF">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_new_transaction"
|
||||
android:layout_width="0dp"
|
||||
<!-- Finish Button -->
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_finish"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="New Transaction"
|
||||
style="@style/PrimaryButton" />
|
||||
android:text="Selesai"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:fontFamily="@font/inter"
|
||||
android:background="@drawable/button_finish_background"
|
||||
app:backgroundTint="@null"
|
||||
app:cornerRadius="8dp"
|
||||
app:rippleColor="#B3000000" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_retry"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="Retry Payment"
|
||||
style="@style/OutlineButton"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- Hidden Components for Compatibility -->
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<TextView android:id="@+id/tv_amount" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_status" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_reference" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_card_info" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_payment_method" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_transaction_id" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_order_id" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_timestamp" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_response_data" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<TextView android:id="@+id/tv_error_details" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<Button android:id="@+id/btn_new_transaction" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<Button android:id="@+id/btn_retry" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
<LinearLayout android:id="@+id/layout_error_details" android:layout_width="0dp" android:layout_height="0dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user