0

I am having the issue sending the JSON with first name and last name whenever name has single quote "'". i.e O'Mally or O'Keef.

Single quote breaks the JSON. How do I pass fistname and lastname variables with single quote in it?

The only way I could get it work by replacing single quote with space using firstname.replace(''', ' '). I have tried other solutions but none of them worked.

Here's code I have.

String jsonString = 
        '{' +
            '"getHostedPaymentPageRequest": {' +
                '"merchantAuthentication": {' +
                    '"name": "{!$Credential.authorize_external_' + communityAbbreviation + '.api_login}"'+',' +
                    '"transactionKey": "{!$Credential.authorize_external_' + communityAbbreviation + '.transaction_key}"'+',' +
                '},' +
                '"refId":"'+recordId+'",'+
                '"transactionRequest": {' +
                    '"transactionType": "authCaptureTransaction",' +
                    '"amount":'+recordDetail.Gift_Amount__c+',' +
                    '"order": {'+
                        '"invoiceNumber":"'+recordDetail.Donation_Invoice_Number__c +'"'+
                    '},'+
                    '"customer": {' +
                        '"email": "'+recordDetail.Email__c+'"'+
                    '},' +
                    '"billTo": {' +
                        '"firstName":"'+recordDetail.First_Name__c+'",' +
                        '"lastName":"'+recordDetail.Last_Name__c+'",' +
                         '"company": "",' +
                         '"address":"'+address+'",'+
                         '"city":"'+recordDetail.City__c+'",' +
                         '"state":"'+recordDetail.State_Province__c+'",' +
                         '"zip":"'+recordDetail.ZIP_Postal_Code__c+'",' +
                         '"country":"'+recordDetail.Country__c+'",' +
                         '"phoneNumber":"'+recordDetail.Phone__c+'"' +
                    '}' +
                '},' +
                '"hostedPaymentSettings": {' +
                    '"setting": [' +
                        '{' +
                            '"settingName": "hostedPaymentReturnOptions",' +
                            '"settingValue": "{\\"showReceipt\\": true, \\"url\\": \\"'+successPage+'\\", \\"urlText\\": \\"Continue\\", \\"cancelUrl\\": \\"'+errorPage+'\\", \\"cancelUrlText\\": \\"Cancel\\"}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentButtonOptions",' +
                            '"settingValue": "{\\"text\\": \\"Pay\\"}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentStyleOptions",' +
                            '"settingValue": "{\\"bgColor\\": \\"blue\\"}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentPaymentOptions",' +
                            '"settingValue": "{\\"cardCodeRequired\\": false, \\"showCreditCard\\": true, \\"showBankAccount\\": false}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentSecurityOptions",' +
                            '"settingValue": "{\\"captcha\\": true}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentShippingAddressOptions",' +
                            '"settingValue": "{\\"show\\": false, \\"required\\": false}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentBillingAddressOptions",' +
                            '"settingValue": "{\\"show\\": true, \\"required\\": false}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentCustomerOptions",' +
                            '"settingValue": "{\\"showEmail\\": false, \\"requiredEmail\\": false, \\"addPaymentProfile\\": true}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentOrderOptions",' +
                            '"settingValue": "{\\"show\\": false, \\"merchantName\\": \\"'+donorName+'\\"}"' +
                        '},' +
                        '{' +
                            '"settingName": "hostedPaymentIFrameCommunicatorUrl",' +
                            '"settingValue": "{\\"url\\": \\"https://mysite.com/special\\"}"' +
                        '}' +
                    ']' +
                '}' +
            '}' +
        '}';
        req.setBody(jsonString);
        Http http = new Http();
        HttpResponse res = http.send(req);

Error:

Response: {"refId":"a1kRK0000XXXXXX","messages":{"resultCode":"Error","message":[{"code":"E00013","text":"Invalid Setting Value. hostedPaymentOrderOptionsmerchantName: has invalid characters."}]}}
4
  • You might want to try replacing it with an escape character e.g. ' --> \' Commented Sep 27 at 0:12
  • I tried using String.escapeSingleQuotes(firstname) but that didn't work.
    – calo
    Commented Sep 27 at 1:42
  • 1
    Please edit to show an example of the generated JSON and the specific error message you get, since single quotes in string values should not cause any trouble. I am wondering if this is bad behaviour on the remote end of the callout.
    – Phil W
    Commented Sep 27 at 6:14
  • Thanks, Phil. I have added Error but I was not sure how to generate JSON here.
    – calo
    Commented Sep 27 at 12:21

1 Answer 1

4

Although it would be interesting to know why you get the issue, you should let the JSON class take care of the json string generation instead of building it yourself :

Map<String, Object> jsonMap = new Map<String, Object>{
        'getHostedPaymentPageRequest' => new Map<String, Object>{
            'merchantAuthentication' => new Map<String, Object>{
                'name' => '{!$Credential.authorize_external_' + communityAbbreviation + '.api_login}',
                'transactionKey' => '{!$Credential.authorize_external_' + communityAbbreviation + '.transaction_key}'
            },
            'refId' => recordId,
            'transactionRequest' => new Map<String, Object>{
                'transactionType' => 'authCaptureTransaction',
                'amount' => recordDetail.Gift_Amount__c,
                'order' => new Map<String, Object>{
                    'invoiceNumber' => recordDetail.Donation_Invoice_Number__c
                },
                'customer' => new Map<String, Object>{
                    'email' => recordDetail.Email__c
                },
                'billTo' => new Map<String, Object>{
                    'firstName' => firstName,
                    'lastName' => lastName,
                    'company' => '',
                    'address' => address,
                    'city' => recordDetail.City__c,
                    'state' => recordDetail.State_Province__c,
                    'zip' => recordDetail.ZIP_Postal_Code__c,
                    'country' => recordDetail.Country__c,
                    'phoneNumber' => recordDetail.Phone__c
                }
            }
        }
    };

// convert map to JSON
String jsonString = JSON.serialize(jsonMap);

Unless the issue is on your endpoint, that should solve it.

5
  • Thanks, Emmanuel. I have update my complete JSON string which has "hostedPaymentSettings" as well. How do I add that to map as it has list to it?
    – calo
    Commented Sep 27 at 12:34
  • @calo it's just a bunch of nested Map<String, Object> for the most part. Map<String, Object> for JSON objects, and List<Object> for JSON arrays. So you'd have "something" => new List<Object>{ new Map<String, Object>{"settingName" => "a thing", "SettingValue" => "other thing"}, new Map<String, Object> { ...
    – Derek F
    Commented Sep 27 at 12:41
  • 3
    Also, if you know your data structure it's often a good idea to create several inner classes and create strongly-typed data to serialize. Helps a lot with visiblity Commented Sep 27 at 13:08
  • Thanks Emmanuel and Derek. That has fixed the first name and last name problem. But I am getting new error: "The element 'getHostedPaymentPageRequest' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd' has invalid child element 'hostedPaymentSettings' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'. List of possible elements expected: 'merchantAuthentication' in namespace 'AnetApi/xml/v1/schema/AnetApiSchema.xsd'.
    – calo
    Commented Sep 27 at 13:57
  • 1
    As Bartosz said it might be easier if instead of maps you'd use classes created to match your endpoints objects. Your error however is weird since the documentation lists hostedPaymentSettings as a child of getHostedPaymentPageRequest. Try to add if you didn't the merchantAuthentication node. Commented Sep 29 at 7:07

You must log in to answer this question.

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