Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add different Transaction Listener's for different Cryptocurrency #765

Open
mxicoderspl opened this issue Oct 15, 2022 · 7 comments

Comments

@mxicoderspl
Copy link

I added Transaction Listeners for some Crypto Currencies with reference to the Transaction extension.

But I got the issue that if I restrict any one currencies listener that restriction will apply to all other currencies in which transaction listener is added.

So how i can create different transaction listeners for every different cryptocurrency?

This is how i implemented the transaction Listener:-

@OverRide
public void init(IExtensionContext ctx) {
super.init(ctx);
this.context_1 = ctx;
}

@OverRide
public boolean isTransactionPreparationApproved(ITransactionPreparation preparation) {
return true; //approve all transactions
}

@OverRide
public boolean isTransactionApproved(ITransactionRequest transactionRequest) {
if(Objects.equals(transactionRequest.getCryptoAmount(), new BigDecimal(1))) {
return true;
}
else {
return false;
}
}

@OverRide
public OutputQueueInsertConfig overrideOutputQueueInsertConfig(ITransactionQueueRequest transactionQueueRequest, OutputQueueInsertConfig outputQueueInsertConfig) {
return null;
}

@OverRide
public Map<String, String> onTransactionCreated(ITransactionDetails transactionDetails) {
String terminalSerialNumber = transactionDetails.getTerminalSerialNumber();
Long previousValue = ticketCounters.get(terminalSerialNumber);
Map<String, String> result = new HashMap<>();
Long value = (previousValue == null) ? 1 : (previousValue + 1);
ticketCounters.put(terminalSerialNumber, value);
result.put("ticket.counter", "" + value);
log.info("Ticket Counter"+ value);
result.put("ticket.previous.counter", ( (previousValue == null) ? "N/A" : "" + previousValue ) ); //result will be stored into database, linked to transdaction record and later be available in ticket template under key ticket.previous.counter
if(transactionDetails.getStatus() == 1){
context_1.addTransactionListener(this);
log.info("The mail address is:- "+transactionDetails.getCryptoAddress());
try{
log.info("Sending the mail");
EmailProviderForVoucher.sendEmailForBuyVoucher(context_1,transactionDetails.getCryptoAddress(),transactionDetails,locale);
}catch(Exception e){
e.printStackTrace();
}
}
return result;
}

@OverRide
public Map<String, String> onTransactionUpdated(ITransactionDetails transactionDetails) {
Map<String, String> result = new HashMap<>();
result.put("last.updated.at", "" + System.currentTimeMillis());
log.info("The mail address is:- "+transactionDetails.getCryptoAddress());
return result;
}

@OverRide
public void receiptSent(IReceiptDetails receiptDetails) {
log.info("Extension - receipt sent from {} - phone: {}, email: {}", receiptDetails.getTerminalSerialNumber(), receiptDetails.getCellphone(), receiptDetails.getEmail());
}

@pvyhnal-generalbytes
Copy link
Contributor

hi, in your listener you can return different results based on the crypto currency of the current transaction, see com.generalbytes.batm.server.extensions.ITransactionRequest#getCryptoCurrency, com.generalbytes.batm.server.extensions.ITransactionDetails#getCryptoCurrency etc. Would that resolve your issue?

@mxicoderspl
Copy link
Author

Hello @pvyhnal-generalbytes,
I am using com.generalbytes.batm.server.extensions.ITransactionRequest.isTransactionApproved method for restricting the transactions. For example, if a particular ATM has distributed 1 BTC, then for that day, users cannot buy BTC from that ATM. When users attempt the transaction, the ATM will accept the banknotes but immediately display an error message stating 'Processing transaction failed.' We want to ensure that if the provided limit is reached for any cryptocurrency, the ATM will not accept the banknotes and will directly decline the transaction, similar to when a user reaches their AML (Anti-Money Laundering) limits.

@pvyhnal-generalbytes
Copy link
Contributor

Hi, try using com.generalbytes.batm.server.extensions.ExtensionContext#isTransactionPreparationApproved instead of com.generalbytes.batm.server.extensions.ExtensionContext#isTransactionApproved

@mxicoderspl
Copy link
Author

Thank you @pvyhnal-generalbytes, I tried this but this always throws NullPointerException for transactionPreparation.getCashAmount() so how to resolve it because I am using this for checking the limits.
Below is the code which throws the exception:-

`private final Map<String,Double> atmPerDayLimitsInEUR = new HashMap<>();
private final Map<String,Double> atmPerDayLimitsInPieces = new HashMap<>();

public void fillLimitsHashmap(){
List allTerminals = context.findAllTerminals();
for(ITerminal terminalDetail: allTerminals){
atmPerDayLimitsInEUR.put(terminalDetail.getSerialNumber(),100.0);
atmPerDayLimitsInPieces.put(terminalDetail.getSerialNumber(),2.0);
}

}

@OverRide
public boolean isTransactionPreparationApproved(ITransactionPreparation transactionPreparation) {

    if(transactionPreparation.getCryptoCurrency().equalsIgnoreCase("VE")) {
        boolean perPieceLimitInEUR = transactionPreparation.getCashAmount().doubleValue() <= 995;
        checkAtmLimitIsUsedInPiece = atmPerDayLimitsInPieces.get(transactionPreparation.getTerminalSerialNumber()) > 0 ;
        checkAtmLimitIsUsedInEUR = transactionPreparation.getCashAmount().doubleValue() <= atmPerDayLimitsInEUR.get(transactionPreparation.getTerminalSerialNumber());
        
        if(transactionPreparation.getCashCurrency().equalsIgnoreCase("EUR")){
            return checkAtmLimitIsUsedInPiece && checkAtmLimitIsUsedInEUR ;
        }
        return true;
    }
	else{
	return true;
	}
}`

By checking the code u can find that we need the transactionPreparation.getCashAmount() at many places so can u please help us that how we can do this?

Thank You.

@pvyhnal-generalbytes
Copy link
Contributor

com.generalbytes.batm.server.extensions.ITransactionPreparation#getCashAmount is not available for Buy transactions because the customer didn't insert any cash into the machine at the time this method is called.

Would this value be useful for you instead?


    /**
     * Maximum cash amount that customer can insert/sell into/to machine
     * @return
     */
    Map<String, BigDecimal> getCashTransactionLimit();

@mxicoderspl
Copy link
Author

Thank you, @pvyhnal-generalbytes, for your valuable response. However, the solution you provided only allows us to check AML/KYC limits per user. Our main requirement is to set limits per ATM per day for a specific cryptocurrency.

Here's an example scenario to illustrate our concern: Let's say we store all transaction amounts per day, and we check that the amount used is 950 Euros, while our set limit for that ATM is 1000 Euros. If a user creates a transaction, they will be allowed to insert notes because that ATMs limit for that day is 950 Euros, which is below our set limit. In this case, the user could potentially insert 200 Euros and buy the cryptocurrency for that amount, which violates our condition.

We need to find a way to restrict this behavior. If we implement the restriction in com.generalbytes.batm.server.extensions.ExtensionContext#isTransactionApproved, the ATM will take the banknote, the transaction will fail, and the ATM will not return the banknote to the user.

Could you please assist me in finding a solution to this problem?

Thank you.

@mxicoderspl
Copy link
Author

Hello @pvyhnal-generalbytes,

Do you have any updates on this so I can close this issue ??

Thank You

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants