From 2a24016637017512df4dc14a55ed078cec8e3d4c Mon Sep 17 00:00:00 2001 From: riz081 Date: Fri, 30 May 2025 19:27:43 +0700 Subject: [PATCH] implement menu debit dan qris --- app/src/main/AndroidManifest.xml | 5 +- .../com/example/bdkipoc/MainActivity.java | 6 +- .../com/example/bdkipoc/QrisActivity.java | 557 ++++++++++++++++++ .../com/example/bdkipoc/ReceiptActivity.java | 37 +- app/src/main/res/layout/activity_qris.xml | 227 +++++++ 5 files changed, 819 insertions(+), 13 deletions(-) create mode 100644 app/src/main/java/com/example/bdkipoc/QrisActivity.java create mode 100644 app/src/main/res/layout/activity_qris.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 373ec7b..8933381 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,7 +33,6 @@ - + + \ No newline at end of file diff --git a/app/src/main/java/com/example/bdkipoc/MainActivity.java b/app/src/main/java/com/example/bdkipoc/MainActivity.java index d6e5c58..9e0c089 100644 --- a/app/src/main/java/com/example/bdkipoc/MainActivity.java +++ b/app/src/main/java/com/example/bdkipoc/MainActivity.java @@ -86,11 +86,11 @@ public class MainActivity extends AppCompatActivity { if (cardId == R.id.card_kartu_kredit) { startActivity(new Intent(MainActivity.this, PaymentActivity.class)); } else if (cardId == R.id.card_kartu_debit) { - Toast.makeText(this, "Kartu Debit Diklik", Toast.LENGTH_SHORT).show(); + startActivity(new Intent(MainActivity.this, PaymentActivity.class)); } else if (cardId == R.id.card_qris) { - startActivity(new Intent(MainActivity.this, TransactionActivity.class)); + startActivity(new Intent(MainActivity.this, QrisActivity.class)); } else if (cardId == R.id.card_bantuan) { - Toast.makeText(this, "Bantuan Diklik", Toast.LENGTH_SHORT).show(); + startActivity(new Intent(MainActivity.this, TransactionActivity.class)); } else if (cardId == R.id.card_info_toko) { Toast.makeText(this, "Info Toko Diklik", Toast.LENGTH_SHORT).show(); } else { diff --git a/app/src/main/java/com/example/bdkipoc/QrisActivity.java b/app/src/main/java/com/example/bdkipoc/QrisActivity.java new file mode 100644 index 0000000..66a996d --- /dev/null +++ b/app/src/main/java/com/example/bdkipoc/QrisActivity.java @@ -0,0 +1,557 @@ +package com.example.bdkipoc; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.os.AsyncTask; +import android.os.Bundle; +import android.util.Log; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Random; +import java.util.UUID; + +public class QrisActivity extends AppCompatActivity { + + private ProgressBar progressBar; + private Button initiatePaymentButton; + private Button simulatePaymentButton; + private ImageView qrCodeImageView; + private TextView statusTextView; + private EditText editTextAmount; + private TextView referenceIdTextView; + private View paymentDetailsLayout; + private View paymentSuccessLayout; + private Button returnToMainButton; + + private String transactionId; + private String transactionUuid; + private String referenceId; + private int amount; + private JSONObject midtransResponse; + + private static final String BACKEND_BASE = "https://be-edc.msvc.app"; + private static final String MIDTRANS_CHARGE_URL = "https://api.sandbox.midtrans.com/v2/charge"; + private static final String MIDTRANS_AUTH = "Basic U0ItTWlkLXNlcnZlci1JM2RJWXdIRzVuamVMeHJCMVZ5endWMUM="; // Replace with your actual key + private static final String WEBHOOK_URL = "https://be-edc.msvc.app/webhooks/midtrans"; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_qris); + + // Set up the toolbar + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + if (getSupportActionBar() != null) { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + getSupportActionBar().setTitle("QRIS Payment"); + } + + // Initialize views + progressBar = findViewById(R.id.progressBar); + initiatePaymentButton = findViewById(R.id.initiatePaymentButton); + simulatePaymentButton = findViewById(R.id.simulatePaymentButton); + qrCodeImageView = findViewById(R.id.qrCodeImageView); + statusTextView = findViewById(R.id.statusTextView); + editTextAmount = findViewById(R.id.editTextAmount); + referenceIdTextView = findViewById(R.id.referenceIdTextView); + paymentDetailsLayout = findViewById(R.id.paymentDetailsLayout); + paymentSuccessLayout = findViewById(R.id.paymentSuccessLayout); + returnToMainButton = findViewById(R.id.returnToMainButton); + + // Generate a random amount between 100,000 and 999,999 + amount = new Random().nextInt(900000) + 100000; + + // Format and display the amount + editTextAmount.setText(""); + editTextAmount.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.showSoftInput(editTextAmount, InputMethodManager.SHOW_IMPLICIT); + } + + // Generate reference ID + referenceId = "ref-" + generateRandomString(8); + referenceIdTextView.setText(referenceId); + + // Set up click listeners + initiatePaymentButton.setOnClickListener(v -> createTransaction()); + simulatePaymentButton.setOnClickListener(v -> simulateWebhook()); + returnToMainButton.setOnClickListener(v -> finish()); + + // Initially hide the QR code and payment success views + paymentDetailsLayout.setVisibility(View.GONE); + paymentSuccessLayout.setVisibility(View.GONE); + simulatePaymentButton.setVisibility(View.GONE); + } + + private void createTransaction() { + progressBar.setVisibility(View.VISIBLE); + initiatePaymentButton.setEnabled(false); + statusTextView.setText("Creating transaction..."); + + new CreateTransactionTask().execute(); + } + + private void displayQrCode(String qrImageUrl) { + new DownloadImageTask().execute(qrImageUrl); + } + + private void simulateWebhook() { + progressBar.setVisibility(View.VISIBLE); + simulatePaymentButton.setEnabled(false); + statusTextView.setText("Processing payment..."); + + new SimulateWebhookTask().execute(); + } + + private void showSuccessScreen() { + paymentDetailsLayout.setVisibility(View.GONE); + paymentSuccessLayout.setVisibility(View.VISIBLE); + statusTextView.setText("Payment successful!"); + progressBar.setVisibility(View.GONE); + } + + private String generateRandomString(int length) { + String chars = "abcdefghijklmnopqrstuvwxyz0123456789"; + StringBuilder sb = new StringBuilder(); + Random random = new Random(); + for (int i = 0; i < length; i++) { + int index = random.nextInt(chars.length()); + sb.append(chars.charAt(index)); + } + return sb.toString(); + } + + private String getServerKey() { + // MIDTRANS_AUTH = 'Basic base64string' + String base64 = MIDTRANS_AUTH.replace("Basic ", ""); + String decoded = android.util.Base64.decode(base64, android.util.Base64.DEFAULT).toString(); + // Format is usually 'SB-Mid-server-xxxx:'. Remove trailing colon if present. + return decoded.replace(":\n", ""); + } + + private String generateSignature(String orderId, String statusCode, String grossAmount, String serverKey) { + String input = orderId + statusCode + grossAmount + serverKey; + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("SHA-512"); + byte[] messageDigest = md.digest(input.getBytes()); + StringBuilder hexString = new StringBuilder(); + for (byte b : messageDigest) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + return hexString.toString(); + } catch (java.security.NoSuchAlgorithmException e) { + return ""; + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return super.onOptionsItemSelected(item); + } + + private class CreateTransactionTask extends AsyncTask { + private String errorMessage; + + @Override + protected Boolean doInBackground(Void... voids) { + try { + // Generate a UUID for the transaction + transactionUuid = UUID.randomUUID().toString(); + + // Create transaction JSON payload + JSONObject payload = new JSONObject(); + payload.put("type", "PAYMENT"); + payload.put("channel_category", "RETAIL_OUTLET"); + payload.put("channel_code", "QRIS"); + payload.put("reference_id", referenceId); + + // Read amount from EditText and log it + String amountText = editTextAmount.getText().toString().trim(); + Log.d("MidtransCharge", "Raw amount text: " + amountText); + + try { + // Parse amount - expecting integer in lowest denomination (Indonesian Rupiah) + amount = Integer.parseInt(amountText); + Log.d("MidtransCharge", "Parsed amount: " + amount); + } catch (NumberFormatException e) { + Log.e("MidtransCharge", "Amount parsing error: " + e.getMessage()); + errorMessage = "Invalid amount format"; + return false; + } + + payload.put("amount", amount); + payload.put("cashflow", "MONEY_IN"); + payload.put("status", "INIT"); + payload.put("device_id", 1); + payload.put("transaction_uuid", transactionUuid); + payload.put("transaction_time_seconds", 0.0); + payload.put("device_code", "PB4K252T00021"); + payload.put("merchant_name", "Marcel Panjaitan"); + payload.put("mid", "71000026521"); + payload.put("tid", "73001500"); + + // Make the API call + URL url = new URI(BACKEND_BASE + "/transactions").toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setRequestProperty("Accept", "application/json"); + conn.setDoOutput(true); + + try (OutputStream os = conn.getOutputStream()) { + byte[] input = payload.toString().getBytes("utf-8"); + os.write(input, 0, input.length); + } + + int responseCode = conn.getResponseCode(); + if (responseCode == 200 || responseCode == 201) { + // Read the response + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + + // Parse the response to get transaction ID + JSONObject jsonResponse = new JSONObject(response.toString()); + JSONObject data = jsonResponse.getJSONObject("data"); + transactionId = String.valueOf(data.getInt("id")); + + // Now generate QRIS via Midtrans + return generateQris(amount); + } else { + // Read error response + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + errorMessage = "Error creating transaction: " + response.toString(); + return false; + } + } catch (Exception e) { + Log.e("MidtransCharge", "Exception: " + e.getMessage(), e); + errorMessage = "Unexpected error: " + e.getMessage(); + return false; + } + } + + private boolean generateQris(int amount) { + try { + // Create QRIS charge JSON payload + JSONObject payload = new JSONObject(); + payload.put("payment_type", "qris"); + + JSONObject transactionDetails = new JSONObject(); + transactionDetails.put("order_id", transactionUuid); + transactionDetails.put("gross_amount", amount); + payload.put("transaction_details", transactionDetails); + + // Log the request details + Log.d("MidtransCharge", "URL: " + MIDTRANS_CHARGE_URL); + Log.d("MidtransCharge", "Authorization: " + MIDTRANS_AUTH); + Log.d("MidtransCharge", "Accept: application/json"); + Log.d("MidtransCharge", "Content-Type: application/json"); + Log.d("MidtransCharge", "X-Override-Notification: " + WEBHOOK_URL); + Log.d("MidtransCharge", "Payload: " + payload.toString()); + + // Make the API call to Midtrans + URL url = new URI(MIDTRANS_CHARGE_URL).toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Accept", "application/json"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setRequestProperty("Authorization", MIDTRANS_AUTH); + conn.setRequestProperty("X-Override-Notification", WEBHOOK_URL); + conn.setDoOutput(true); + + try (OutputStream os = conn.getOutputStream()) { + byte[] input = payload.toString().getBytes("utf-8"); + os.write(input, 0, input.length); + } + + int responseCode = conn.getResponseCode(); + if (responseCode == 200 || responseCode == 201) { + InputStream inputStream = conn.getInputStream(); + if (inputStream != null) { + BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + + // Parse the response + midtransResponse = new JSONObject(response.toString()); + return true; + } else { + Log.e("MidtransCharge", "HTTP " + responseCode + ": No input stream available"); + errorMessage = "Error generating QRIS: HTTP " + responseCode + ": No input stream available"; + return false; + } + } else { + InputStream errorStream = conn.getErrorStream(); + if (errorStream != null) { + BufferedReader br = new BufferedReader(new InputStreamReader(errorStream, "utf-8")); + StringBuilder errorResponse = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + errorResponse.append(responseLine.trim()); + } + Log.e("MidtransCharge", "HTTP " + responseCode + ": " + errorResponse.toString()); + errorMessage = "Error generating QRIS: HTTP " + responseCode + ": " + errorResponse.toString(); + } else { + Log.e("MidtransCharge", "HTTP " + responseCode + ": No error stream available"); + errorMessage = "Error generating QRIS: HTTP " + responseCode + ": No error stream available"; + } + return false; + } + } catch (Exception e) { + Log.e("MidtransCharge", "Exception: " + e.getMessage(), e); + errorMessage = "Unexpected error: " + e.getMessage(); + return false; + } + } + + @Override + protected void onPostExecute(Boolean success) { + if (success && midtransResponse != null) { + try { + // Extract needed values from midtransResponse + JSONObject actions = midtransResponse.getJSONArray("actions").getJSONObject(0); + String qrImageUrl = actions.getString("url"); + + // Extract transaction_id + String transactionId = midtransResponse.getString("transaction_id"); + String transactionTime = midtransResponse.getString("transaction_time"); + String acquirer = midtransResponse.getString("acquirer"); + String merchantId = midtransResponse.getString("merchant_id"); + String exactGrossAmount = midtransResponse.getString("gross_amount"); + + // Log everything before launching activity + Log.d("MidtransCharge", "Creating QrisResultActivity intent with:"); + Log.d("MidtransCharge", "qrImageUrl: " + qrImageUrl); + Log.d("MidtransCharge", "amount: " + amount); + Log.d("MidtransCharge", "referenceId: " + referenceId); + Log.d("MidtransCharge", "transactionUuid (orderId): " + transactionUuid); + Log.d("MidtransCharge", "transaction_id: " + transactionId); + Log.d("MidtransCharge", "exactGrossAmount: " + exactGrossAmount); + + // Instead of showing QR inline, launch QrisResultActivity + Intent intent = new Intent(QrisActivity.this, QrisResultActivity.class); + intent.putExtra("qrImageUrl", qrImageUrl); + intent.putExtra("amount", amount); + intent.putExtra("referenceId", referenceId); + intent.putExtra("orderId", transactionUuid); // Order ID + intent.putExtra("transactionId", transactionId); // Actual Midtrans transaction_id + intent.putExtra("grossAmount", exactGrossAmount); // Exact gross amount from response + intent.putExtra("transactionTime", transactionTime); // For timestamp + intent.putExtra("acquirer", acquirer); + intent.putExtra("merchantId", merchantId); + + try { + startActivity(intent); + } catch (Exception e) { + Log.e("MidtransCharge", "Failed to start QrisResultActivity: " + e.getMessage(), e); + Toast.makeText(QrisActivity.this, "Error launching QR display: " + e.getMessage(), Toast.LENGTH_LONG).show(); + } + return; + } catch (JSONException e) { + Log.e("MidtransCharge", "QRIS response JSON error: " + e.getMessage(), e); + Toast.makeText(QrisActivity.this, "Error processing QRIS response", Toast.LENGTH_LONG).show(); + } + } else { + String message = (errorMessage != null && !errorMessage.isEmpty()) ? errorMessage : "Unknown error occurred. Please check Logcat for details."; + Toast.makeText(QrisActivity.this, message, Toast.LENGTH_LONG).show(); + initiatePaymentButton.setEnabled(true); + } + progressBar.setVisibility(View.GONE); + } + } + + private class DownloadImageTask extends AsyncTask { + @Override + protected Bitmap doInBackground(String... urls) { + String urlDisplay = urls[0]; + Bitmap bitmap = null; + try { + URL url = new URI(urlDisplay).toURL(); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoInput(true); + connection.connect(); + java.io.InputStream input = connection.getInputStream(); + bitmap = android.graphics.BitmapFactory.decodeStream(input); + } catch (Exception e) { + e.printStackTrace(); + } + return bitmap; + } + + @Override + protected void onPostExecute(Bitmap result) { + if (result != null) { + qrCodeImageView.setImageBitmap(result); + } else { + Toast.makeText(QrisActivity.this, "Error loading QR code image", Toast.LENGTH_LONG).show(); + } + } + } + + private class SimulateWebhookTask extends AsyncTask { + private String errorMessage; + + @Override + protected Boolean doInBackground(Void... voids) { + try { + // Wait a moment to simulate real-world timing + Thread.sleep(1500); + + // Get server key and prepare signature + String serverKey = getServerKey(); + String grossAmount = String.valueOf(amount) + ".00"; + String signatureKey = generateSignature( + transactionUuid, + "200", + grossAmount, + serverKey + ); + + // Create webhook payload + JSONObject payload = new JSONObject(); + payload.put("transaction_type", "on-us"); + payload.put("transaction_time", midtransResponse.getString("transaction_time")); + payload.put("transaction_status", "settlement"); + payload.put("transaction_id", midtransResponse.getString("transaction_id")); + payload.put("status_message", "midtrans payment notification"); + payload.put("status_code", "200"); + payload.put("signature_key", signatureKey); + payload.put("settlement_time", midtransResponse.getString("transaction_time")); + payload.put("payment_type", "qris"); + payload.put("order_id", transactionUuid); + payload.put("merchant_id", midtransResponse.getString("merchant_id")); + payload.put("issuer", midtransResponse.getString("acquirer")); + payload.put("gross_amount", grossAmount); + payload.put("fraud_status", "accept"); + payload.put("currency", "IDR"); + payload.put("acquirer", midtransResponse.getString("acquirer")); + payload.put("shopeepay_reference_number", ""); + payload.put("reference_id", referenceId); + + // Call the webhook URL + URL url = new URI(WEBHOOK_URL).toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/json"); + conn.setRequestProperty("Accept", "application/json"); + conn.setDoOutput(true); + + try (OutputStream os = conn.getOutputStream()) { + byte[] input = payload.toString().getBytes("utf-8"); + os.write(input, 0, input.length); + } + + int responseCode = conn.getResponseCode(); + if (responseCode == 200 || responseCode == 201) { + // Wait briefly to allow the backend to process + Thread.sleep(2000); + return checkTransactionStatus(); + } else { + // Read error response + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + errorMessage = "Error simulating payment: " + response.toString(); + return false; + } + } catch (Exception e) { + errorMessage = "Error: " + e.getMessage(); + return false; + } + } + + private boolean checkTransactionStatus() { + try { + // Check transaction status + URL url = new URI(BACKEND_BASE + "/transactions/" + transactionId).toURL(); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setRequestProperty("Accept", "application/json"); + + int responseCode = conn.getResponseCode(); + if (responseCode == 200) { + // Read the response + BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8")); + StringBuilder response = new StringBuilder(); + String responseLine; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + + // Parse the response + JSONObject jsonResponse = new JSONObject(response.toString()); + JSONObject data = jsonResponse.getJSONObject("data"); + String status = data.getString("status"); + + return status.equalsIgnoreCase("SUCCESS"); + } else { + errorMessage = "Error checking transaction status. HTTP response code: " + responseCode; + return false; + } + } catch (Exception e) { + errorMessage = "Error checking transaction status: " + e.getMessage(); + return false; + } + } + + @Override + protected void onPostExecute(Boolean success) { + if (success) { + showSuccessScreen(); + } else { + String message = (errorMessage != null && !errorMessage.isEmpty()) ? errorMessage : "Unknown error occurred. Please check Logcat for details."; + Toast.makeText(QrisActivity.this, message, Toast.LENGTH_LONG).show(); + simulatePaymentButton.setEnabled(true); + } + progressBar.setVisibility(View.GONE); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/bdkipoc/ReceiptActivity.java b/app/src/main/java/com/example/bdkipoc/ReceiptActivity.java index 1478d5b..1d49e2a 100644 --- a/app/src/main/java/com/example/bdkipoc/ReceiptActivity.java +++ b/app/src/main/java/com/example/bdkipoc/ReceiptActivity.java @@ -95,10 +95,10 @@ public class ReceiptActivity extends AppCompatActivity { } private void setupClickListeners() { - // Back navigation - backNavigation.setOnClickListener(v -> navigateBack()); - backArrow.setOnClickListener(v -> navigateBack()); - toolbarTitle.setOnClickListener(v -> navigateBack()); + // Back navigation - Goes back to previous activity (PaymentActivity) + backNavigation.setOnClickListener(v -> navigateBackToPrevious()); + backArrow.setOnClickListener(v -> navigateBackToPrevious()); + toolbarTitle.setOnClickListener(v -> navigateBackToPrevious()); // Action buttons printButton.setOnClickListener(v -> handlePrintReceipt()); @@ -191,24 +191,43 @@ public class ReceiptActivity extends AppCompatActivity { } private void handleFinish() { - // Finish and return to main screen - navigateBack(); + // Navigate to MainActivity/Home Page when "Selesai" button is pressed + navigateToHomePage(); } - private void navigateBack() { - // You can navigate back to main activity or finish + private void navigateBackToPrevious() { + // Navigate back to PaymentActivity (previous activity) Intent intent = new Intent(this, PaymentActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); } + private void navigateToHomePage() { + // Navigate to MainActivity/Home Page when "Selesai" button is pressed + Intent intent = new Intent(this, MainActivity.class); + + // Clear all previous activities from the stack and start fresh + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); + + // Optional: Add success message to show in MainActivity + intent.putExtra("transaction_completed", true); + intent.putExtra("transaction_amount", getIntent().getStringExtra("transaction_amount")); + + startActivity(intent); + finish(); + + // Show success message + showToast("Transaksi berhasil diselesaikan!"); + } + private void showToast(String message) { android.widget.Toast.makeText(this, message, android.widget.Toast.LENGTH_SHORT).show(); } @Override public void onBackPressed() { - navigateBack(); + // Back button behavior - goes back to previous activity + navigateBackToPrevious(); } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_qris.xml b/app/src/main/res/layout/activity_qris.xml new file mode 100644 index 0000000..dc89329 --- /dev/null +++ b/app/src/main/res/layout/activity_qris.xml @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +