From a47137f62460a645a098bda6f5bd668da9d56b37 Mon Sep 17 00:00:00 2001 From: MooN <56061215+MgKyawLay@users.noreply.github.com> Date: Fri, 12 Dec 2025 01:01:42 +0630 Subject: [PATCH] qr close order api qr close order api called on back press of generated qr --- .../com/utsmm/kbz/ui/kpay/KPayViewModel.java | 47 +++++++ .../kbz/ui/kpay/QRTransactionFragment.java | 55 +++++++- .../utsmyanmar/baselib/di/NetworkModule.java | 4 - .../baselib/network/KPayApiService.java | 4 + .../baselib/network/model/KPayQRRequest.java | 128 ++++++++++++++++++ .../baselib/network/model/KPayQRResponse.java | 47 +++++++ .../utsmyanmar/baselib/repo/Repository.java | 5 + 7 files changed, 283 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java index f7ec8a0..14e1aff 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java +++ b/app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java @@ -276,6 +276,44 @@ public class KPayViewModel extends ViewModel { return qrRequest; } + public KPayQRRequest.CloseOrderRequest closeQrOrder(String merchOrderId, String mid){ + String currentTime = String.valueOf(System.currentTimeMillis()); + String nonceStr = generateNonceStr(); // Generate random nonce_str + + Map bizContentMap = new HashMap<>(); + bizContentMap.put("merch_order_id", merchOrderId); + bizContentMap.put("merch_code", mid); + bizContentMap.put("appid", appId); + + Map requestMap = new HashMap<>(); + requestMap.put("timestamp", currentTime); + requestMap.put("nonce_str", nonceStr); + requestMap.put("method", "kbz.payment.closeorder"); + requestMap.put("version", "3.0"); + requestMap.put("biz_content", bizContentMap); + + String sign = Sign.INSTANCE.generateSign(requestMap, appKey); + + KPayQRRequest.CloseOrderRequest.Request.BizContent bizContent = new KPayQRRequest.CloseOrderRequest.Request.BizContent( + merchOrderId, + mid, + appId + ); + + KPayQRRequest.CloseOrderRequest.Request requestBody = new KPayQRRequest.CloseOrderRequest.Request( + currentTime, + "kbz.payment.closeorder", + nonceStr, + "SHA256", + sign, + "3.0", + bizContent + ); + + KPayQRRequest.CloseOrderRequest request = new KPayQRRequest.CloseOrderRequest(requestBody); + + return request; + } public KPayQRQueryRequest.QRQueryRequest getQrStatus(String merchOrderId, String mid) { @@ -317,6 +355,8 @@ public class KPayViewModel extends ViewModel { return request; } + + @Inject public KPayViewModel(Repository repository) { this.repository = repository; @@ -398,4 +438,11 @@ public class KPayViewModel extends ViewModel { public Observable kPayRefund(KPayRefund.RefundRequest refundRequest) { return repository.kPayRefund(refundRequest); } + + public Observable closeQrOrderApi( + KPayQRRequest.CloseOrderRequest request + ) { + return repository.qrCloseOrder(request); + } + } \ No newline at end of file diff --git a/app/src/main/java/com/utsmm/kbz/ui/kpay/QRTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/kpay/QRTransactionFragment.java index e5326fc..d86d5c1 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/kpay/QRTransactionFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/kpay/QRTransactionFragment.java @@ -13,6 +13,7 @@ import com.utsmm.kbz.util.EReceiptUtil; import com.utsmm.kbz.util.enums.TransResultStatus; import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.network.model.KPayQRQueryRequest; +import com.utsmyanmar.baselib.network.model.KPayQRRequest; import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest; import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.baselib.util.TimeoutCallback; @@ -188,9 +189,15 @@ public class QRTransactionFragment extends DataBindingFragment implements DataBi setUpTimeout(); setUpCountDown(); - - - + requireActivity().getOnBackPressedDispatcher().addCallback( + getViewLifecycleOwner(), + new androidx.activity.OnBackPressedCallback(true) { + @Override + public void handleOnBackPressed() { + showExitConfirmation(); + } + } + ); } private void setUpCountDown() { @@ -419,6 +426,48 @@ public class QRTransactionFragment extends DataBindingFragment implements DataBi popBackStack(); } + private void showExitConfirmation() { + new androidx.appcompat.app.AlertDialog.Builder(requireContext()) + .setTitle("Exit QR Transaction?") + .setMessage("Are you sure you want to exit?") + .setCancelable(false) + .setPositiveButton("Yes", (dialog, which) -> { + dialog.dismiss(); + if (sharedViewModel.isEcr.getValue() != null) { + if (sharedViewModel.isEcr.getValue()) { + finishECR(); + } + } + closeOrder(); + popBackStack(); + }) + .setNegativeButton("No", (dialog, which) -> dialog.dismiss()) + .show(); + } + + private void closeOrder(){ + String refNo = sharedViewModel.qrRefNum.getValue(); + String mid = TransactionUtil.getInstance().getQRMerchantId(); + if (refNo == null || mid == null) { + LogUtil.e("QR", "Missing ref or merchant ID. Cannot close order."); + return; + } + + KPayQRRequest.CloseOrderRequest request = kPayViewModel.closeQrOrder(refNo, mid); + kPayViewModel.closeQrOrderApi(request) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe( + resp -> { + LogUtil.d("CloseOrder", "Result = " + resp.getResponse().getResult()); + LogUtil.d("CloseOrder", "Msg = " + resp.getResponse().getMsg()); + }, + err -> { + LogUtil.e("CloseOrder", "Error = " + err.getMessage()); + } + ); + } + private String getECRResponseMessage() { sharedViewModel.payDetail.setValue(payDetail); diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java index 94b7c30..9821f58 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java @@ -394,10 +394,8 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { String pass = SystemParamsOperation.getInstance().getCertificatePassword(); if (TextUtils.isEmpty(pass)) { - LogUtil.e("RefundCert", "Certificate password is missing!"); pass = "test123"; } - LogUtil.d("kmk", "pass => "+pass); char[] password = pass.toCharArray(); @@ -407,9 +405,7 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { Security.addProvider(new BouncyCastleProvider()); String clientPath = SystemParamsOperation.getInstance().getCertClientFilePath(); - LogUtil.d("kmk", "client path => " + clientPath); String caPath = SystemParamsOperation.getInstance().getCertFilePath(); - LogUtil.d("kmk", "ca path => " + caPath); if (TextUtils.isEmpty(clientPath) || TextUtils.isEmpty(caPath)) { LogUtil.e("RefundCert", "Certificate files missing."); diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java index c8385d8..d521070 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java @@ -11,6 +11,7 @@ import com.utsmyanmar.baselib.network.model.WaveStatusRequest; import io.reactivex.rxjava3.core.Observable; import retrofit2.http.Body; import retrofit2.http.POST; +import retrofit2.http.Url; public interface KPayApiService { @@ -20,4 +21,7 @@ public interface KPayApiService { @POST("queryorder") Observable checkStatus(@Body KPayQRQueryRequest.QRQueryRequest waveStatusRequest); + + @POST + Observable closeOrder(@Url String url, @Body KPayQRRequest.CloseOrderRequest closeOrderRequest); } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRRequest.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRRequest.java index 154fcb7..45d7635 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRRequest.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRRequest.java @@ -446,4 +446,132 @@ public class KPayQRRequest { } + public static class CloseOrderRequest { + + @SerializedName("Request") + private Request request; + + public CloseOrderRequest(Request request) { + this.request = request; + } + + public Request getRequest() { + return request; + } + + public void setRequest(Request request) { + this.request = request; + } + + public static class Request { + @SerializedName("timestamp") + private String timestamp; + + @SerializedName("method") + private String method; + + @SerializedName("nonce_str") + private String nonceStr; + + @SerializedName("sign_type") + private String signType; + + @SerializedName("sign") + private String sign; + + @SerializedName("version") + private String version; + + @SerializedName("biz_content") + private BizContent bizContent; + + public Request(String timestamp, String method, String nonceStr, String signType, + String sign, String version, BizContent bizContent) { + this.timestamp = timestamp; + this.method = method; + this.nonceStr = nonceStr; + this.signType = signType; + this.sign = sign; + this.version = version; + this.bizContent = bizContent; + } + + public static class BizContent { + + @SerializedName("merch_order_id") + private String merchOrderId; + + @SerializedName("merch_code") + private String merchCode; + + @SerializedName("appid") + private String appId; + + public BizContent(String merchOrderId, String merchCode, String appId) { + this.merchOrderId = merchOrderId; + this.merchCode = merchCode; + this.appId = appId; + } + + public String getMerchOrderId() { + return merchOrderId; + } + + public String getMerchCode() { + return merchCode; + } + + public String getAppId() { + return appId; + } + } + } + } + + public static class CloseOrderResponse { + + @SerializedName("Response") + private ResponseBody response; + + public ResponseBody getResponse() { + return response; + } + + public void setResponse(ResponseBody response) { + this.response = response; + } + + public static class ResponseBody { + + @SerializedName("result") + private String result; + + @SerializedName("code") + private String code; + + @SerializedName("msg") + private String msg; + + @SerializedName("merch_order_id") + private String merchOrderId; + + @SerializedName("nonce_str") + private String nonceStr; + + @SerializedName("sign_type") + private String signType; + + @SerializedName("sign") + private String sign; + + public String getResult() { return result; } + public String getCode() { return code; } + public String getMsg() { return msg; } + public String getMerchOrderId() { return merchOrderId; } + public String getNonceStr() { return nonceStr; } + public String getSignType() { return signType; } + public String getSign() { return sign; } + } + } + } \ No newline at end of file diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRResponse.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRResponse.java index 7a158a8..0551e12 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRResponse.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/KPayQRResponse.java @@ -152,4 +152,51 @@ public class KPayQRResponse { } } } + + public static class CloseOrderResponse { + + @SerializedName("Response") + private ResponseBody response; + + public ResponseBody getResponse() { + return response; + } + + public void setResponse(ResponseBody response) { + this.response = response; + } + + public static class ResponseBody { + + @SerializedName("result") + private String result; + + @SerializedName("code") + private String code; + + @SerializedName("msg") + private String msg; + + @SerializedName("merch_order_id") + private String merchOrderId; + + @SerializedName("nonce_str") + private String nonceStr; + + @SerializedName("sign_type") + private String signType; + + @SerializedName("sign") + private String sign; + + public String getResult() { return result; } + public String getCode() { return code; } + public String getMsg() { return msg; } + public String getMerchOrderId() { return merchOrderId; } + public String getNonceStr() { return nonceStr; } + public String getSignType() { return signType; } + public String getSign() { return sign; } + } + } + } \ No newline at end of file diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java index 3b1104c..cd41d0d 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java @@ -80,6 +80,11 @@ public class Repository { return kPayApiService.qrRequest(request); } + public Observable qrCloseOrder(KPayQRRequest.CloseOrderRequest request){ + String url = "https://api.kbzpay.com/payment/gateway/uat/closeorder"; + return kPayApiService.closeOrder(url, request); + } + public Observable qrStatusCheck(KPayQRQueryRequest.QRQueryRequest request) { return kPayApiService.checkStatus(request); }