1

My flow has a screen where the users enters a value in a currency field that has 2 decimal places and that value gets passed to a variable in an Apex Action within the flow. For some reason, when I debug the flow, it shows it passing the decimal places (ex. $200.00) to the Apex, but once it gets passed to my Apex variable it is represented as only a whole number (200).

I'm using a Decimal variable in my method so I'm not sure why it is dropping the decimal points.

Do I need to specify the decimal points on the Decimal variable? I would think that it would just carry over.

Here's my flow debug:

enter image description here

And Here's what is showing in my debug log for the Apex Action:

enter image description here

This is how I'm declaring my variable in the Apex:

public without sharing class chargentAPI_PartialRefund_Flow {
public class FlowInputs {
    @InvocableVariable public String transactionId;
    @InvocableVariable public Decimal refundAmount;
}

EDIT to Add Screen shots of Error by 3rd party app:

Approved:

enter image description here

Not Approved:

enter image description here

Here is the full code:

    public without sharing class chargentAPI_PartialRefund_Flow {
//Set the flow Input variables
public class FlowInputs {
    @InvocableVariable public String transactionId;
    @InvocableVariable public Decimal refundAmount;

    
}

@InvocableMethod
//Pass the input variables to the list
public static void issueRefund (List<FlowInputs> Request) {
    String transactionId = request[0].transactionId;
    Decimal refundAmount = request[0].refundAmount;
    
    //Add the variables to the callout
    callout(transactionId, refundAmount);
}

@future(callout = true)
//Pass the variables to the future callout
public static void callout(String transactionId, Decimal refundAmount) {
    
    //Generate the input data based on Chargent API documentation
    List<ChargentApiInput> createChargentApiInput = New List<ChargentApiInput>();
    ChargentApiInput gtwyData = new ChargentApiInput();
    gtwyData.ObjectId = transactionId;
    gtwyData.amount = refundAmount;
    createChargentApiInput.add(gtwyData);
    
    String jsonRefundData = JSON.serialize(gtwyData);
    System.debug('JSON Input: '+jsonRefundData);
    

        //Invocate refund click json method on Chargent API with json data as a parameter
        ChargentOrders.TChargentOperations.TChargentResult refundResult = ChargentOrders.TChargentOperations.RefundTransaction_ClickJSON(jsonRefundData);
        System.debug('Refund Result :'+refundResult.Message);
        
        
    String jsonString = refundResult.responseData;
        //GetResponse respsonse = (GetResponse) JSON.deserialize(jsonString, GetResponse.class);
       JSONParser parser = JSON.createParser(jsonString);
      parser.nextToken();
      parser.nextValue();
      ID recordId = parser.getIdValue();
       System.debug('Record Id' + recordId);
                  
        
       ChargentOrders__Transaction__c newTransaction = [SELECT Id, Main_Transaction__c FROM ChargentOrders__Transaction__c WHERE Id = :recordId];
       newTransaction.Main_Transaction__c = TransactionId;
        
       UPDATE newTransaction;
        
          
    
}

class ChargentApiInput{
    String ObjectId;
    Decimal Amount;
}
}
9
  • It's possible that this is just an artifact of how things are printed to debug logs. If you change your refund amount to be something other than a whole number (like 200.42), do you still see the same result?
    – Derek F
    Jan 5, 2022 at 17:45
  • @DerekF you are right that when I put 299.99 it passes with the decimal as 299.99. But I need it to pass a whole number as 200.00 too otherwise it causes my 3rd party app to throw an error stating that 200 is not acceptable. The app still works, but I don't want this error to be logged. Is there a way to check if the decimal places are being passed properly besides the debug logs?
    – Heather
    Jan 5, 2022 at 17:52
  • Or is there a way to FORCE the decimal places to always be present?
    – Heather
    Jan 5, 2022 at 17:54
  • Decimal.setScale(2)? Jan 5, 2022 at 18:00
  • Since the decimal places do appear for non-whole numbers, I'd be inclined to believe that there is no issue here. The fractional portion (.00) should still be present (i.e. there shouldn't be anything that needs to be "forced"), Salesforce just isn't showing it in the log. Are you actually seeing your third party app returning a warning/error, or are you just trying to get ahead of a potential problem?
    – Derek F
    Jan 5, 2022 at 18:01

1 Answer 1

2

Change the class

class ChargentApiInput{
  String ObjectId;
  Decimal Amount;
}

to:

class ChargentApiInput{
  String ObjectId;
  Decimal Amount;

  ChargentApiInput withObjectId(String val) {this.ObjectId = val; return this;}
  ChargentApiInput withAmount(Decimal val) {
      String s = String.valueOf(val.setScale(2));
      this.Amount = Decimal.valueOf(s);
      return this;
}

and then these lines:

ChargentApiInput gtwyData = new ChargentApiInput();
gtwyData.ObjectId = transactionId;
gtwyData.amount = refundAmount;
createChargentApiInput.add(gtwyData);

to:

ChargentApiInput gtwyData = new ChargentApiInput()
  .withObjectId(transactionId)
  .withAmount(refundAmount)
);
createChargentApiInput.add(gtwyData);
String jsonRefundData = JSON.serialize(gtwyData);

This anon apex was used to verify the approach:

Decimal d;
Decimal d2;
d = 200;
String s = String.valueOf(d.setScale(2));
d2 = Decimal.valueOf(s);
System.debug(JSON.serialize(d2));

prints: 200.00
11
  • Thank you for this! I can see in the log that converting to string at this point DOES retain the decimal points, but with this change, I'm now getting the error: Invalid conversion from runtime type String to Decimal.
    – Heather
    Jan 6, 2022 at 12:54
  • What line does the error occur on ? If you do further operations on Amount and expect it to be decimal, you may need an intermediate someDecimal = Decimal.valueOf(xxx.Amount)
    – cropredy
    Jan 6, 2022 at 15:57
  • I believe it is occurring on Line 42 which is when we execute the apps refund method. I'm looking at the API documentation and it is saying that RefundTransaction_ClickJSON parameter of Amount is Decimal so could it be that it's trying to convert the String Amount I'm declaring back to a Decimal? If that is the case is there any other way I can be sure the Decimal places are kept? This is Line 42 ChargentOrders.TChargentOperations.TChargentResult refundResult = ChargentOrders.TChargentOperations.RefundTransaction_ClickJSON(jsonRefundData);
    – Heather
    Jan 6, 2022 at 17:39
  • you'll have to use edit and expose the method ChargentOrders.TChargentOperations.RefundTransaction_ClickJSON
    – cropredy
    Jan 6, 2022 at 18:03
  • unfortunately, I don't think I can do that because the method is part of a class in a managed package....so am I just stuck and will have to go back to the app provider?
    – Heather
    Jan 6, 2022 at 18:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .