Connect Salesforce with Authorize.Net

Connect Salesforce with Authorize.Net

Hi All, We all know about authorize.net. Its the most common payment gateway used to make payment transaction from Website. We can also use it with Salesforce to setup payment gateway where our users can make a purchase and do payments as well.

Its very easy to connect Salesforce with Authorize.net. In this post we will use Sandbox account to make transaction but you can follow same steps for live transactions.

  • First Sign up for a Sandbox account here. Screenshot_2.pngNow you will get Login Id and Transaction Key. Store them in some place so that we can use them later.

Screenshot_1

  •  Now there are various method from which we can make a payment, Authorize a payment, Charge a card later and void the transaction. In case of Production URl we need to change the base URl.
  • Also make sure you add the base URL in remote site setting.

Screenshot_3.png


public with sharing class AuthorizePayment {

private string APIkey = '********';
private string transKey = '************';
private string Amt = '5';
private string cardNum = '5424000000000015';
private string expdate = '1220';
private string cvvCode = '999';

//Method to make payment and charge the card
public void makePayment(){
//Getting access token from Paypal
HttpRequest req1 = new HttpRequest();
req1.setMethod('POST');
req1.setEndpoint('https://apitest.authorize.net/xml/v1/request.api');
req1.setHeader('content-type', 'application/json');
/*
Production URL: https://api.authorize.net/xml/v1/request.api

XSD URL: https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd
*/

string messageBody1 ='{"createTransactionRequest":{"merchantAuthentication":{"name":"'+APIkey+'","transactionKey":"'+transKey+'"},'
+'"refId":"123456","transactionRequest":{"transactionType":"authCaptureTransaction","amount":"'+Amt+'","payment":{"creditCard":'
+'{"cardNumber":"'+cardNum+'","expirationDate":"'+expdate+'","cardCode":"'+cvvCode+'"}},"lineItems":{"lineItem":{"itemId":"1","name":"vase",'
+'"description":"Cannes logo","quantity":"18","unitPrice":"45.00"}},"tax":{"amount":"4.26","name":"level2 tax name","description":"level2 tax"},'
+'"duty":{"amount":"8.55","name":"duty name","description":"duty description"},"shipping":{"amount":"4.26","name":"level2 tax name",'+
'"description":"level2 tax"},"poNumber":"456654","customer":{"id":"99999456654"},"billTo":{"firstName":"Ellen","lastName":"Johnson",'+
'"company":"Souveniropolis","address":"14 Main Street","city":"Pecan Springs","state":"TX","zip":"44628","country":"USA"},"shipTo":'+
'{"firstName":"China","lastName":"Bayles","company":"Thyme for Tea","address":"12 Main Street","city":"Pecan Springs","state":"TX","zip":"44628",'+
'"country":"USA"},"customerIP":"192.168.1.1","transactionSettings":{"setting":{"settingName":"testRequest","settingValue":"false"}},'+
'"userFields":{"userField":[{"name":"MerchantDefinedFieldName1","value":"MerchantDefinedFieldValue1"},{"name":"favorite_color","value":"blue"}]}}}}';

req1.setHeader('Content-length', String.valueOf(messageBody1.length()));
req1.setBody(messageBody1);

req1.setTimeout(60*1000);
Http h1 = new Http();
String resp1;
HttpResponse res1 = h1.send(req1);
resp1 = res1.getBody();
Map<String,object> responseMap =(Map<String,object>)JSON.deserializeUntyped(res1.getBody().substring(1,res1.getBody().length())) ;
for(string keyStr : responseMap.keyset())
system.debug(keyStr+'-----------Response------------------>>>>'+responseMap.get(keyStr));
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Confirm, resp1));

}

//Method to authorize the card to make the payment later
public void authorizecard(){
HttpRequest req1 = new HttpRequest();
req1.setMethod('POST');
req1.setEndpoint('https://apitest.authorize.net/xml/v1/request.api');
req1.setHeader('content-type', 'application/json');
/*
Production URL: https://api.authorize.net/xml/v1/request.api

XSD URL: https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd
*/

string messageBody1 ='{ "createTransactionRequest": { "merchantAuthentication": { "name":"'+APIkey+'","transactionKey":"'+transKey+'" }, '+
'"refId": "123456", "transactionRequest": { "transactionType": "authOnlyTransaction", "amount": "'+Amt+'", "payment": { "creditCard": '+
'{ "cardNumber":"'+cardNum+'","expirationDate":"'+expdate+'","cardCode":"'+cvvCode+'" } }, "lineItems": { "lineItem": { "itemId": "1", '+
'"name": "vase", "description": "Cannes logo", "quantity": "18", "unitPrice": "45.00" } }, "tax": { "amount": "4.26", "name": "level2 tax name",'+
'"description": "level2 tax" }, "duty": { "amount": "8.55", "name": "duty name", "description": "duty description" }, "shipping": '+
'{ "amount": "4.26", "name": "level2 tax name", "description": "level2 tax" }, "poNumber": "456654", "customer": { "id": "99999456654" },'+
' "billTo": { "firstName": "Ellen", "lastName": "Johnson", "company": "Souveniropolis", "address": "14 Main Street", "city": "Pecan Springs",'+
' "state": "TX", "zip": "44628", "country": "USA" }, "shipTo": { "firstName": "China", "lastName": "Bayles", "company": "Thyme for Tea", '+
'"address": "12 Main Street", "city": "Pecan Springs", "state": "TX", "zip": "44628", "country": "USA" }, "customerIP": "192.168.1.1", '+
'"transactionSettings": { "setting": { "settingName": "testRequest", "settingValue": "false" } }, "userFields": { "userField": [ '+
'{ "name": "MerchantDefinedFieldName1", "value": "MerchantDefinedFieldValue1" }, { "name": "favorite_color", "value": "blue" } ] } } } }';

req1.setHeader('Content-length', String.valueOf(messageBody1.length()));
req1.setBody(messageBody1);

req1.setTimeout(60*1000);
Http h1 = new Http();
String resp1;
HttpResponse res1 = h1.send(req1);
resp1 = res1.getBody();
Map<String,object> responseMap =(Map<String,object>)JSON.deserializeUntyped(res1.getBody().substring(1,res1.getBody().length())) ;
for(string keyStr : responseMap.keyset())
system.debug(keyStr+'-----------Response------------------>>>>'+responseMap.get(keyStr));
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Confirm, resp1));

}

//Method for refund the settled payment
public void refundPay(){
HttpRequest req1 = new HttpRequest();
req1.setMethod('POST');
req1.setEndpoint('https://apitest.authorize.net/xml/v1/request.api');
req1.setHeader('content-type', 'application/json');
/*
Production URL: https://api.authorize.net/xml/v1/request.api

XSD URL: https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd
*/

string messageBody1 ='{ "createTransactionRequest": { "merchantAuthentication": { "name":"'+APIkey+'","transactionKey":"'+transKey+'" },'+
' "refId": "123456", "transactionRequest": { "transactionType": "refundTransaction", "amount": "5.00", "payment": { "creditCard": '+
'{ "cardNumber":"'+cardNum+'","expirationDate":"'+expdate+'" } }, "refTransId": "60024747323" } } }';

req1.setHeader('Content-length', String.valueOf(messageBody1.length()));
req1.setBody(messageBody1);

req1.setTimeout(60*1000);
Http h1 = new Http();
String resp1;
HttpResponse res1 = h1.send(req1);
resp1 = res1.getBody();
Map<String,object> responseMap =(Map<String,object>)JSON.deserializeUntyped(res1.getBody().substring(1,res1.getBody().length())) ;
for(string keyStr : responseMap.keyset())
system.debug(keyStr+'-----------Response------------------>>>>'+responseMap.get(keyStr));
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Confirm, resp1));

}

//method for cancel the unseattled payment
public void voidPay(){
HttpRequest req1 = new HttpRequest();
req1.setMethod('POST');
req1.setEndpoint('https://apitest.authorize.net/xml/v1/request.api');
req1.setHeader('content-type', 'application/json');
/*
Production URL: https://api.authorize.net/xml/v1/request.api

XSD URL: https://api.authorize.net/xml/v1/schema/AnetApiSchema.xsd
*/

string messageBody1 ='{ "createTransactionRequest": { "merchantAuthentication": { "name":"'+APIkey+'","transactionKey":"'+transKey+'" },'+
'"refId": "123456", "transactionRequest": { "transactionType": "voidTransaction", "refTransId": "60024747323" } } }';

req1.setHeader('Content-length', String.valueOf(messageBody1.length()));
req1.setBody(messageBody1);

req1.setTimeout(60*1000);
Http h1 = new Http();
String resp1;
HttpResponse res1 = h1.send(req1);
resp1 = res1.getBody();Map<String,object> responseMap =(Map<String,object>)JSON.deserializeUntyped(res1.getBody().substring(1,res1.getBody().length())) ;
for(string keyStr : responseMap.keyset())
system.debug(keyStr+'-----------Response------------------>>>>'+responseMap.get(keyStr));
ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Confirm, resp1));
}

}

  • From the transaction response you will get the transId which you can n cancellation and other processes. You can read more about them in detail from here.

So now you can setup a payment gateway in your force.com site or for internal user. If you like this post or want to add something let me know in comments section.

Happy Programming 🙂

Advertisements

Connect Salesforce with Box.com Part 2

Connect Salesforce with Box.com Part 2

Hi All, In my previous post Connect Salesforce with Box.com (The Integration series) I have shared how can you create a Box.com app and authorize the user from Salesforce.

In this post I am sharing two utility method to create a folder on box.com and upload a file on box.com. There are various other methods are available but for starting I have found these two most useful.

So first create a folder in box.com platform you can use this method.


private void createfolder(String fileName, string parentid)
{
String url = 'https://api.box.com/2.0/folders';
string authorizationHeader = 'Bearer '+Accesstoken ;

HttpRequest req = new HttpRequest();
req.setheader('Authorization',authorizationHeader);
req.setBody('{"name":"'+fileName+'", "parent":{"id":"0"}}');
req.setMethod('POST');
req.setEndpoint(url);

Http h = new Http();
Httpresponse resp = h.send(req);
System.debug(resp.getbody()+'-----------------------'+resp); 
}

 

To upload a file in Box.com platform use this utility method.

 


private void uploadFileCode(String folderId,Attachment file,String token){
String boundary = '----------------------------356sdf986eff';
String header = '--'+boundary+'\nContent-Disposition: form-data; name=&quot;file&quot;; filename=&quot;'+fileName+'&quot;;\nContent-Type: application/octet-stream';

String footer = '--'+boundary+'--';
String headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
while(headerEncoded.endsWith('=')){
header+=' ';
headerEncoded = EncodingUtil.base64Encode(Blob.valueOf(header+'\r\n\r\n'));
}
String bodyEncoded = EncodingUtil.base64Encode(file.body);

Blob bodyBlob = null;
String last4Bytes = bodyEncoded.substring(bodyEncoded.length()-4,bodyEncoded.length());
if(last4Bytes.endsWith('==')) {

last4Bytes = last4Bytes.substring(0,2) + '0K';
bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;

String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
} else if(last4Bytes.endsWith('=')) {
last4Bytes = last4Bytes.substring(0,3) + 'N';
bodyEncoded = bodyEncoded.substring(0,bodyEncoded.length()-4) + last4Bytes;

footer = '\n' + footer;
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
} else {
// Prepend the CR LF to the footer
footer = '\r\n' + footer;
String footerEncoded = EncodingUtil.base64Encode(Blob.valueOf(footer));
bodyBlob = EncodingUtil.base64Decode(headerEncoded+bodyEncoded+footerEncoded);
}

String sUrl = 'https://upload.box.com/api/2.0/files/content?parent_id='+folderId;
HttpRequest req = new HttpRequest();
req.setHeader('Content-Type','multipart/form-data; boundary='+boundary);
req.setMethod('POST');
req.setEndpoint(sUrl);
req.setBodyAsBlob(bodyBlob);
req.setTimeout(60000);
req.setHeader('Authorization', 'Bearer '+token);
req.setHeader('Content-Length',String.valueof(req.getBodyAsBlob().size()));
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getbody()+'-----------------------'+res);
}

These are the two methods which you can use to create a folder and upload file.

Do you have anything to add or like this post or any other thing to share please share them in comments.

 

Connect Salesforce with Box.com

Connect Salesforce with Box.com

Hi All, We all know that’s how costly it is to store data in Salesforce.com. So we always want to store data in third party so that we can reduce the cost. Thats why today I am sharing the authorization process between Salesforce and Box.com in my Integration series.

For this first you need to go to Box.com for a Developer account which you can create here.

After successful account creation you need to create an App to get the key and token. You can create an app here.

After creation your app will look like this.

Screenshot_6

 

 

Give your Visualforce page url as redirect URL. Now use the below code to perform the authorization process.

Controller:

public with sharing class BoxComIntegration {
    //Fetched from URL
    private String code ;
    private string key = 'llpm**************2ks8';
    private string secret = 'LMh**************jCmK2fDHK' ;
    private string redirect_uri = 'https://c.ap1.visual.force.com/apex/BoxComUpload';
    
    public BoxComIntegration()
    {
        code = ApexPages.currentPage().getParameters().get('code') ;  
        //Get the access token once we have code
        if(code != '' && code != null)
        {
            AccessToken() ;
        }
        
    }
    
    public PageReference BoxAuth()
    {
        //Authenticating
        PageReference pg = new PageReference(BoxAuthUri (key , redirect_uri)) ;
        return pg ;
    }
    
    public String BoxAuthUri(String Clientkey,String redirect_uri)
    {
        String key = EncodingUtil.urlEncode(Clientkey,'UTF-8');
        String uri = EncodingUtil.urlEncode(redirect_uri,'UTF-8');
        String authuri = '';
        authuri = 'https://account.box.com/api/oauth2/authorize?'+
        'client_id='+key+
        '&response_type=code'+
        '&redirect_uri='+uri+
        '&state=security_token%3D138r5719ru3e1%26urldfrgdgvrev';
        
        return authuri;
    }
    
    
    public void AccessToken()
    {
        //Getting access token from google
        HttpRequest req = new HttpRequest();
        req.setMethod('POST');
        req.setEndpoint('https://api.box.com/oauth2/token');
        String messageBody = 'code='+code+'&client_id='+key+'&client_secret='+secret+'&redirect_uri='+redirect_uri+'&grant_type=authorization_code';
        req.setHeader('Content-length', String.valueOf(messageBody.length()));
        req.setBody(messageBody);
        req.setTimeout(60*1000);

        Http h = new Http();
        String resp;
        HttpResponse res = h.send(req);
        resp = res.getBody();
         Map<String,object> responseMap =(Map<String,object>)JSON.deserializeUntyped(res.getBody()) ;  
          String token =  String.valueOf(responseMap.get('access_token'));
         system.debug('***************'+token);
   }
}

VF Page:

<apex:page controller="BoxComIntegration">
<apex:form >
    <apex:pageblock > 
        <apex:commandbutton action="{!BoxAuth}" value="Authentication">
    </apex:commandbutton></apex:pageblock>
</apex:form>
</apex:page>

Screenshot_7

Also add two Base URLs in remote site setting. And now you are all set when you run this code you will get access token and using that token you can easily upload, download the files.

Screenshot_8

Let me know if you like this post. Do you have anything to add in the post. let me know in comments section.

Also check second post of Integration series connect salesforce with box com part 2