transaction update
This commit is contained in:
parent
da8bcf17cc
commit
991f77dabe
@ -20,7 +20,9 @@ import java.util.Locale;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
public class ReceiptActivity extends AppCompatActivity {
|
public class ReceiptActivity extends AppCompatActivity {
|
||||||
|
|
||||||
@ -286,10 +288,6 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
return fallbackPaymentMethod != null ? fallbackPaymentMethod : "QRIS";
|
return fallbackPaymentMethod != null ? fallbackPaymentMethod : "QRIS";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ✅ ENHANCED: Dynamic acquirer detection from webhook data
|
|
||||||
* This method tries to get the REAL acquirer instead of defaulting to GoPay
|
|
||||||
*/
|
|
||||||
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,7 +297,7 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
switch (acq) {
|
switch (acq) {
|
||||||
// E-Wallet acquirers
|
// E-Wallet acquirers
|
||||||
case "gopay": return "GoPay";
|
case "gopay": return "GoPay";
|
||||||
case "shopeepay": return "ShopeePay";
|
case "shopeepay": return "ShopeePay";
|
||||||
case "ovo": return "OVO";
|
case "ovo": return "OVO";
|
||||||
case "dana": return "DANA";
|
case "dana": return "DANA";
|
||||||
case "linkaja": return "LinkAja";
|
case "linkaja": return "LinkAja";
|
||||||
@ -323,9 +321,6 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
case "bsi":
|
case "bsi":
|
||||||
case "bsi_va": return "BSI";
|
case "bsi_va": return "BSI";
|
||||||
case "maybank": return "Maybank";
|
case "maybank": return "Maybank";
|
||||||
case "mega": return "Bank Mega";
|
|
||||||
case "btn": return "BTN";
|
|
||||||
case "bukopin": return "Bukopin";
|
|
||||||
|
|
||||||
// Credit card acquirers
|
// Credit card acquirers
|
||||||
case "visa": return "Visa";
|
case "visa": return "Visa";
|
||||||
@ -343,12 +338,6 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
case "kredivo": return "Kredivo";
|
case "kredivo": return "Kredivo";
|
||||||
case "indodana": return "Indodana";
|
case "indodana": return "Indodana";
|
||||||
|
|
||||||
// Other acquirers
|
|
||||||
case "emoney": return "E-Money";
|
|
||||||
case "flazz": return "Flazz";
|
|
||||||
case "tapcash": return "TapCash";
|
|
||||||
case "brizzi": return "Brizzi";
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Return capitalized version of acquirer if not in mapping
|
// Return capitalized version of acquirer if not in mapping
|
||||||
return capitalizeFirstLetter(acquirer);
|
return capitalizeFirstLetter(acquirer);
|
||||||
@ -361,11 +350,16 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
if (referenceId != null && !referenceId.isEmpty()) {
|
if (referenceId != null && !referenceId.isEmpty()) {
|
||||||
Log.d("ReceiptActivity", "🔍 QRIS detected, fetching real acquirer for: " + referenceId);
|
Log.d("ReceiptActivity", "🔍 QRIS detected, fetching real acquirer for: " + referenceId);
|
||||||
|
|
||||||
// Try to get real acquirer from webhook data asynchronously
|
// Try to get real acquirer from webhook data synchronously for initial load
|
||||||
fetchRealAcquirerFromWebhook(referenceId);
|
String realAcquirer = fetchRealAcquirerSync(referenceId);
|
||||||
|
if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
|
||||||
|
Log.d("ReceiptActivity", "✅ Found real acquirer synchronously: " + realAcquirer);
|
||||||
|
return getCardTypeFromAcquirer(realAcquirer, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
// ✅ IMPROVED: Instead of defaulting to GoPay, show generic "QRIS" until real acquirer is found
|
// If sync fetch failed, try async and show generic QRIS for now
|
||||||
return "QRIS"; // Will be updated when real acquirer is found
|
fetchRealAcquirerFromWebhook(referenceId);
|
||||||
|
return "QRIS"; // ✅ FIXED: Show QRIS instead of defaulting to GoPay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,7 +367,7 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
if (channelCode != null && !channelCode.isEmpty()) {
|
if (channelCode != null && !channelCode.isEmpty()) {
|
||||||
String code = channelCode.toUpperCase();
|
String code = channelCode.toUpperCase();
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case "QRIS": return "QRIS"; // ✅ CHANGED: Generic QRIS instead of GoPay
|
case "QRIS": return "QRIS"; // ✅ FIXED: Generic QRIS instead of GoPay
|
||||||
case "DEBIT": return "Debit";
|
case "DEBIT": return "Debit";
|
||||||
case "CREDIT": return "Credit";
|
case "CREDIT": return "Credit";
|
||||||
case "BCA": return "BCA";
|
case "BCA": return "BCA";
|
||||||
@ -385,19 +379,97 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// STEP 4: Final fallback
|
// STEP 4: Final fallback
|
||||||
return fallbackCardType != null ? fallbackCardType : "Unknown"; // ✅ CHANGED: Unknown instead of GoPay
|
return fallbackCardType != null ? fallbackCardType : "Unknown"; // ✅ FIXED: Unknown instead of GoPay
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fetchRealAcquirerSync(String referenceId) {
|
||||||
|
try {
|
||||||
|
Log.d("ReceiptActivity", "🔍 Sync search for acquirer: " + referenceId);
|
||||||
|
|
||||||
|
String queryUrl = "https://be-edc.msvc.app/api-logs?limit=50&sortOrder=DESC&sortColumn=created_at";
|
||||||
|
|
||||||
|
URL url = new URL(queryUrl);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("GET");
|
||||||
|
conn.setRequestProperty("Accept", "application/json");
|
||||||
|
conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
|
||||||
|
conn.setConnectTimeout(5000); // Short timeout for sync call
|
||||||
|
conn.setReadTimeout(5000);
|
||||||
|
|
||||||
|
if (conn.getResponseCode() == 200) {
|
||||||
|
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = br.readLine()) != null) {
|
||||||
|
response.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
org.json.JSONObject json = new org.json.JSONObject(response.toString());
|
||||||
|
org.json.JSONArray results = json.optJSONArray("results");
|
||||||
|
|
||||||
|
if (results != null && results.length() > 0) {
|
||||||
|
// Search for the most recent settlement/success transaction
|
||||||
|
for (int i = 0; i < results.length(); i++) {
|
||||||
|
org.json.JSONObject log = results.getJSONObject(i);
|
||||||
|
org.json.JSONObject reqBody = log.optJSONObject("request_body");
|
||||||
|
|
||||||
|
if (reqBody != null) {
|
||||||
|
String logReferenceId = reqBody.optString("reference_id", "");
|
||||||
|
String logTransactionStatus = reqBody.optString("transaction_status", "");
|
||||||
|
String logAcquirer = reqBody.optString("acquirer", "");
|
||||||
|
String logIssuer = reqBody.optString("issuer", "");
|
||||||
|
|
||||||
|
// Check for direct reference match
|
||||||
|
boolean isDirectMatch = referenceId.equals(logReferenceId);
|
||||||
|
|
||||||
|
// Check custom_field1 for refresh tracking
|
||||||
|
boolean isRefreshMatch = false;
|
||||||
|
String customField1 = reqBody.optString("custom_field1", "");
|
||||||
|
if (!customField1.isEmpty()) {
|
||||||
|
try {
|
||||||
|
org.json.JSONObject customData = new org.json.JSONObject(customField1);
|
||||||
|
String originalReference = customData.optString("original_reference", "");
|
||||||
|
String appReferenceId = customData.optString("app_reference_id", "");
|
||||||
|
if (referenceId.equals(originalReference) || referenceId.equals(appReferenceId)) {
|
||||||
|
isRefreshMatch = true;
|
||||||
|
}
|
||||||
|
} catch (org.json.JSONException e) {
|
||||||
|
// Ignore parsing errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this log matches our reference
|
||||||
|
if (isDirectMatch || isRefreshMatch) {
|
||||||
|
// Prioritize settlement/success status
|
||||||
|
if (logTransactionStatus.equals("settlement") ||
|
||||||
|
logTransactionStatus.equals("capture") ||
|
||||||
|
logTransactionStatus.equals("success")) {
|
||||||
|
|
||||||
|
// Extract acquirer (prefer acquirer field over issuer)
|
||||||
|
String foundAcquirer = !logAcquirer.isEmpty() ? logAcquirer : logIssuer;
|
||||||
|
if (!foundAcquirer.isEmpty() && !foundAcquirer.equalsIgnoreCase("qris")) {
|
||||||
|
Log.d("ReceiptActivity", "📋 Sync found acquirer: " + foundAcquirer + " (status: " + logTransactionStatus + ")");
|
||||||
|
return foundAcquirer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("ReceiptActivity", "❌ Sync acquirer fetch error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // No acquirer found
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* ✅ ENHANCED: Fetch real acquirer from webhook data for QRIS transactions
|
|
||||||
* This method searches webhook logs to find the actual acquirer used
|
|
||||||
*/
|
|
||||||
private void fetchRealAcquirerFromWebhook(String referenceId) {
|
private void fetchRealAcquirerFromWebhook(String referenceId) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Log.d("ReceiptActivity", "🔍 Searching for real acquirer for reference: " + referenceId);
|
Log.d("ReceiptActivity", "🔍 Async search for real acquirer: " + referenceId);
|
||||||
|
|
||||||
// Search webhook logs for this reference with broader search
|
|
||||||
String queryUrl = "https://be-edc.msvc.app/api-logs?limit=100&sortOrder=DESC&sortColumn=created_at";
|
String queryUrl = "https://be-edc.msvc.app/api-logs?limit=100&sortOrder=DESC&sortColumn=created_at";
|
||||||
|
|
||||||
URL url = new URL(queryUrl);
|
URL url = new URL(queryUrl);
|
||||||
@ -423,7 +495,7 @@ public class ReceiptActivity extends AppCompatActivity {
|
|||||||
String realAcquirer = searchForRealAcquirer(results, referenceId);
|
String realAcquirer = searchForRealAcquirer(results, referenceId);
|
||||||
|
|
||||||
if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
|
if (realAcquirer != null && !realAcquirer.isEmpty() && !realAcquirer.equalsIgnoreCase("qris")) {
|
||||||
Log.d("ReceiptActivity", "✅ Found real acquirer: " + realAcquirer + " for reference: " + referenceId);
|
Log.d("ReceiptActivity", "✅ Async found real acquirer: " + realAcquirer + " for reference: " + referenceId);
|
||||||
|
|
||||||
// Update UI on main thread
|
// Update UI on main thread
|
||||||
final String displayAcquirer = getCardTypeFromAcquirer(realAcquirer, null, null);
|
final String displayAcquirer = getCardTypeFromAcquirer(realAcquirer, null, null);
|
||||||
|
@ -14,6 +14,7 @@ import androidx.core.content.ContextCompat;
|
|||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream; // ✅ ADDED: Missing import
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -211,14 +212,14 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
return "Rp. " + formatted;
|
return "Rp. " + formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ✅ FIXED: Enhanced status checking with comprehensive search
|
||||||
private void checkMidtransStatus(String referenceId, TextView statusTextView) {
|
private void checkMidtransStatus(String referenceId, TextView statusTextView) {
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
Log.d("TransactionAdapter", "🔍 Comprehensive status check for reference: " + referenceId);
|
Log.d("TransactionAdapter", "🔍 Comprehensive status check for reference: " + referenceId);
|
||||||
|
|
||||||
// STEP 1: Query ALL webhook logs (tidak filter specific order_id)
|
// STEP 1: Query webhook logs untuk semua order_id yang terkait
|
||||||
// Karena kita perlu cari semua order_id yang terkait dengan reference_id ini
|
String queryUrl = "https://be-edc.msvc.app/api-logs?limit=200&sortOrder=DESC&sortColumn=created_at";
|
||||||
String queryUrl = "https://be-edc.msvc.app/api-logs?limit=100&sortOrder=DESC&sortColumn=created_at";
|
|
||||||
|
|
||||||
URL url = new URL(queryUrl);
|
URL url = new URL(queryUrl);
|
||||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
@ -238,14 +239,14 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
JSONObject json = new JSONObject(response.toString());
|
JSONObject json = new JSONObject(response.toString());
|
||||||
JSONArray results = json.optJSONArray("results");
|
JSONArray results = json.optJSONArray("results");
|
||||||
|
|
||||||
String realStatus = "INIT"; // Default
|
String finalStatus = "INIT"; // Default
|
||||||
String foundOrderId = null;
|
String foundOrderId = null;
|
||||||
String foundTransactionStatus = "";
|
String foundAcquirer = null;
|
||||||
|
|
||||||
if (results != null && results.length() > 0) {
|
if (results != null && results.length() > 0) {
|
||||||
Log.d("TransactionAdapter", "📊 Processing " + results.length() + " log entries");
|
Log.d("TransactionAdapter", "📊 Processing " + results.length() + " log entries");
|
||||||
|
|
||||||
// STEP 2: Comprehensive search untuk semua kemungkinan relasi
|
// STEP 2: Comprehensive search dengan multiple matching strategies
|
||||||
for (int i = 0; i < results.length(); i++) {
|
for (int i = 0; i < results.length(); i++) {
|
||||||
JSONObject log = results.getJSONObject(i);
|
JSONObject log = results.getJSONObject(i);
|
||||||
JSONObject reqBody = log.optJSONObject("request_body");
|
JSONObject reqBody = log.optJSONObject("request_body");
|
||||||
@ -254,6 +255,7 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
String logOrderId = reqBody.optString("order_id", "");
|
String logOrderId = reqBody.optString("order_id", "");
|
||||||
String logTransactionStatus = reqBody.optString("transaction_status", "");
|
String logTransactionStatus = reqBody.optString("transaction_status", "");
|
||||||
String logReferenceId = reqBody.optString("reference_id", "");
|
String logReferenceId = reqBody.optString("reference_id", "");
|
||||||
|
String logAcquirer = reqBody.optString("acquirer", "");
|
||||||
|
|
||||||
// ✅ METHOD 1: Direct reference_id match
|
// ✅ METHOD 1: Direct reference_id match
|
||||||
boolean isDirectMatch = referenceId.equals(logReferenceId);
|
boolean isDirectMatch = referenceId.equals(logReferenceId);
|
||||||
@ -265,10 +267,10 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
try {
|
try {
|
||||||
JSONObject customData = new JSONObject(customField1);
|
JSONObject customData = new JSONObject(customField1);
|
||||||
String originalReference = customData.optString("original_reference", "");
|
String originalReference = customData.optString("original_reference", "");
|
||||||
if (referenceId.equals(originalReference)) {
|
String appReferenceId = customData.optString("app_reference_id", "");
|
||||||
|
if (referenceId.equals(originalReference) || referenceId.equals(appReferenceId)) {
|
||||||
isRefreshMatch = true;
|
isRefreshMatch = true;
|
||||||
Log.d("TransactionAdapter", "🔄 Found refresh match: " + logOrderId +
|
Log.d("TransactionAdapter", "🔄 Found refresh match: " + logOrderId);
|
||||||
" (original ref: " + originalReference + ")");
|
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
// Ignore custom field parsing errors
|
// Ignore custom field parsing errors
|
||||||
@ -283,10 +285,10 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
JSONObject item = itemDetails.optJSONObject(j);
|
JSONObject item = itemDetails.optJSONObject(j);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
String itemName = item.optString("name", "");
|
String itemName = item.optString("name", "");
|
||||||
if (itemName.contains("(Ref: " + referenceId + ")")) {
|
if (itemName.contains("(Ref: " + referenceId + ")") ||
|
||||||
|
itemName.contains("- " + referenceId)) {
|
||||||
isItemMatch = true;
|
isItemMatch = true;
|
||||||
Log.d("TransactionAdapter", "📦 Found item match: " + logOrderId +
|
Log.d("TransactionAdapter", "📦 Found item match: " + logOrderId);
|
||||||
" (item: " + itemName + ")");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,52 +302,63 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
Log.d("TransactionAdapter", "🎯 MATCH FOUND!");
|
Log.d("TransactionAdapter", "🎯 MATCH FOUND!");
|
||||||
Log.d("TransactionAdapter", " Order ID: " + logOrderId);
|
Log.d("TransactionAdapter", " Order ID: " + logOrderId);
|
||||||
Log.d("TransactionAdapter", " Status: " + logTransactionStatus);
|
Log.d("TransactionAdapter", " Status: " + logTransactionStatus);
|
||||||
Log.d("TransactionAdapter", " Reference: " + logReferenceId);
|
Log.d("TransactionAdapter", " Acquirer: " + logAcquirer);
|
||||||
Log.d("TransactionAdapter", " Match Type: " +
|
Log.d("TransactionAdapter", " Match Type: " +
|
||||||
(isDirectMatch ? "DIRECT" : "") +
|
(isDirectMatch ? "DIRECT " : "") +
|
||||||
(isRefreshMatch ? "REFRESH" : "") +
|
(isRefreshMatch ? "REFRESH " : "") +
|
||||||
(isItemMatch ? "ITEM" : ""));
|
(isItemMatch ? "ITEM" : ""));
|
||||||
|
|
||||||
// Priority check: settlement > capture > success > pending > init
|
// ✅ PRIORITY SYSTEM: settlement > capture > success > pending > init
|
||||||
if (logTransactionStatus.equals("settlement") ||
|
if (logTransactionStatus.equals("settlement") ||
|
||||||
logTransactionStatus.equals("capture") ||
|
logTransactionStatus.equals("capture") ||
|
||||||
logTransactionStatus.equals("success")) {
|
logTransactionStatus.equals("success")) {
|
||||||
realStatus = "PAID";
|
finalStatus = "PAID";
|
||||||
foundOrderId = logOrderId;
|
foundOrderId = logOrderId;
|
||||||
foundTransactionStatus = logTransactionStatus;
|
foundAcquirer = logAcquirer;
|
||||||
Log.d("TransactionAdapter", "✅ PAYMENT CONFIRMED: " + logOrderId + " -> " + logTransactionStatus);
|
Log.d("TransactionAdapter", "✅ PAYMENT CONFIRMED: " + logOrderId + " -> " + logTransactionStatus);
|
||||||
break; // Found paid status, stop searching
|
break; // Found paid status, stop searching
|
||||||
} else if (logTransactionStatus.equals("pending") && realStatus.equals("INIT")) {
|
} else if (logTransactionStatus.equals("pending") && finalStatus.equals("INIT")) {
|
||||||
realStatus = "PENDING";
|
finalStatus = "PENDING";
|
||||||
foundOrderId = logOrderId;
|
foundOrderId = logOrderId;
|
||||||
foundTransactionStatus = logTransactionStatus;
|
foundAcquirer = logAcquirer;
|
||||||
Log.d("TransactionAdapter", "⏳ PENDING found: " + logOrderId);
|
Log.d("TransactionAdapter", "⏳ PENDING found: " + logOrderId);
|
||||||
|
} else if (logTransactionStatus.equals("expire") || logTransactionStatus.equals("cancel")) {
|
||||||
|
if (finalStatus.equals("INIT")) { // Only update if no better status found
|
||||||
|
finalStatus = "FAILED";
|
||||||
|
foundOrderId = logOrderId;
|
||||||
|
foundAcquirer = logAcquirer;
|
||||||
|
Log.d("TransactionAdapter", "❌ FAILED status: " + logOrderId + " -> " + logTransactionStatus);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d("TransactionAdapter", "🔍 FINAL RESULT for " + referenceId + ":");
|
Log.d("TransactionAdapter", "🔍 FINAL RESULT for " + referenceId + ":");
|
||||||
Log.d("TransactionAdapter", " Status: " + realStatus);
|
Log.d("TransactionAdapter", " Status: " + finalStatus);
|
||||||
Log.d("TransactionAdapter", " Order ID: " + (foundOrderId != null ? foundOrderId : "N/A"));
|
Log.d("TransactionAdapter", " Order ID: " + (foundOrderId != null ? foundOrderId : "N/A"));
|
||||||
Log.d("TransactionAdapter", " Midtrans Status: " + (foundTransactionStatus != null ? foundTransactionStatus : "N/A"));
|
Log.d("TransactionAdapter", " Acquirer: " + (foundAcquirer != null ? foundAcquirer : "N/A"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEP 3: Update UI di main thread
|
// STEP 3: Update UI di main thread
|
||||||
final String finalStatus = realStatus;
|
final String displayStatus = finalStatus;
|
||||||
final String finalOrderId = foundOrderId;
|
final String detectedAcquirer = foundAcquirer;
|
||||||
final String finalTransactionStatus = foundTransactionStatus;
|
|
||||||
|
|
||||||
statusTextView.post(() -> {
|
statusTextView.post(() -> {
|
||||||
statusTextView.setText(finalStatus);
|
statusTextView.setText(displayStatus);
|
||||||
StyleHelper.applyStatusTextColor(statusTextView, statusTextView.getContext(), finalStatus);
|
StyleHelper.applyStatusTextColor(statusTextView, statusTextView.getContext(), displayStatus);
|
||||||
|
|
||||||
Log.d("TransactionAdapter", "🎨 UI UPDATED:");
|
Log.d("TransactionAdapter", "🎨 UI UPDATED:");
|
||||||
Log.d("TransactionAdapter", " Reference: " + referenceId);
|
Log.d("TransactionAdapter", " Reference: " + referenceId);
|
||||||
Log.d("TransactionAdapter", " Display Status: " + finalStatus);
|
Log.d("TransactionAdapter", " Display Status: " + displayStatus);
|
||||||
Log.d("TransactionAdapter", " Found Order: " + (finalOrderId != null ? finalOrderId : "N/A"));
|
Log.d("TransactionAdapter", " Detected Acquirer: " + (detectedAcquirer != null ? detectedAcquirer : "Unknown"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ✅ BONUS: Update backend jika status berubah ke PAID
|
||||||
|
if (finalStatus.equals("PAID")) {
|
||||||
|
updateBackendTransactionStatus(referenceId, finalStatus, foundOrderId, detectedAcquirer);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.w("TransactionAdapter", "⚠️ API call failed with code: " + conn.getResponseCode());
|
Log.w("TransactionAdapter", "⚠️ API call failed with code: " + conn.getResponseCode());
|
||||||
statusTextView.post(() -> {
|
statusTextView.post(() -> {
|
||||||
@ -364,6 +377,57 @@ public class TransactionAdapter extends RecyclerView.Adapter<TransactionAdapter.
|
|||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ✅ NEW METHOD: Update backend transaction status when payment confirmed
|
||||||
|
*/
|
||||||
|
private void updateBackendTransactionStatus(String referenceId, String status, String orderId, String acquirer) {
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
Log.d("TransactionAdapter", "🔄 Updating backend status for reference: " + referenceId);
|
||||||
|
|
||||||
|
JSONObject updatePayload = new JSONObject();
|
||||||
|
updatePayload.put("status", status);
|
||||||
|
updatePayload.put("payment_status", status);
|
||||||
|
updatePayload.put("paid_order_id", orderId);
|
||||||
|
updatePayload.put("detected_acquirer", acquirer);
|
||||||
|
updatePayload.put("updated_at", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
|
||||||
|
updatePayload.put("settlement_time", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(new Date()));
|
||||||
|
|
||||||
|
String updateUrl = "https://be-edc.msvc.app/transactions/update-by-reference";
|
||||||
|
URL url = new URL(updateUrl);
|
||||||
|
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||||
|
conn.setRequestMethod("POST");
|
||||||
|
conn.setRequestProperty("Content-Type", "application/json");
|
||||||
|
conn.setRequestProperty("Accept", "application/json");
|
||||||
|
conn.setRequestProperty("User-Agent", "BDKIPOCApp/1.0");
|
||||||
|
conn.setDoOutput(true);
|
||||||
|
conn.setConnectTimeout(15000);
|
||||||
|
conn.setReadTimeout(15000);
|
||||||
|
|
||||||
|
JSONObject requestBody = new JSONObject();
|
||||||
|
requestBody.put("reference_id", referenceId);
|
||||||
|
requestBody.put("update_data", updatePayload);
|
||||||
|
|
||||||
|
try (OutputStream os = conn.getOutputStream()) {
|
||||||
|
byte[] input = requestBody.toString().getBytes("utf-8");
|
||||||
|
os.write(input, 0, input.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int responseCode = conn.getResponseCode();
|
||||||
|
Log.d("TransactionAdapter", "📥 Backend update response: " + responseCode);
|
||||||
|
|
||||||
|
if (responseCode == 200 || responseCode == 201) {
|
||||||
|
Log.d("TransactionAdapter", "✅ Backend status updated successfully");
|
||||||
|
} else {
|
||||||
|
Log.e("TransactionAdapter", "❌ Backend update failed: " + responseCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("TransactionAdapter", "❌ Backend update error: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format created_at date to readable format
|
* Format created_at date to readable format
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user