You need to sign in to do that
Don't have an account?

Cybersource silent order API integration
Hi Guys,
Has anyone tried Cybersource silent order API integration with Salesforce? Looking for some help.
Thanks in advance.
Thanks,
Prashant.
Has anyone tried Cybersource silent order API integration with Salesforce? Looking for some help.
Thanks in advance.
Thanks,
Prashant.
Did you find solution for the above. We are looking for the same.Please help if you knew the solution
Yes i had implmented it last month. I have used couple of references to get the good understading.
Look at the reply by moggy to below thread.I have used the same approach except i havent created my own page where customer needs to fill card details etc rather i posted eveything to cybersource server.
https://developer.salesforce.com/forums/?id=906F00000008zDzIAI (http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_Hosted_Checkout/Secure_Acceptance_Hosted_Checkout.pdf)
Also below cybersource document was a big help too-
http://apps.cybersource.com/library/documentation/dev_guides/Secure_Acceptance_Hosted_Checkout/Secure_Acceptance_Hosted_Checkout.pdf
Give it a try and let me know how it goes.
Thanks,
Prashant.
I followed moggy's guide, but I'm facing the error message of "You are not authorized to view this page. The transaction has not been processed."
Can anyone kindly advise where I went wrong in my code?
I am alos getting same issue "You are not authorized to view this page. The transaction has not been processed.". Please help.
Thanks.
The reason for my failure was wrong timestamp. I had to minus 8 hours (I'm based in a GMT + 8) from system.now() as the signed_date_field parameter value.
Hello,
we are trying to access CyberSource hosted checkout page and using tokenization in salesforce.
In salesforce we have created a custom Page asking for required fields fields like "Amount and currency fields" and once user click on submit button , page will redirect user to Cybersource hosted page.
I was trying to access the above approaches but getting error 403 not authorized to access the page.
We have the cybersouce logins with details like profile Id,access key and secret key.
Any help in this regard will be appreciated.
I've managed to do something similar, successfully before.
I can help :).
Its great to see your reply, I have followed your approach till now and its nice to see you.
To give you some background, I am into a basic POC feasibility where we would like to use Cybersouce checkout hosted page to be accessed using salesforce and create a token to be used for transactions.
My page is taking just two inputs may be currency and amount fields and once these details along with signed/unsigned data are submmitted , we should be shown cybersource hosted checkout page to enter the card level details.
I have the profile Id, access key and Secret keys which I got from Cybersource testing environment.
Going with this approach, everytime I make a submit it is giving me error 403 you are not authorized to view this page. Below is my Sample Vf and controller.
No problem glad to help.
Just one issue I've spotted at first glance (sorry I don't have time today to take a closer look):
1. For transaction_type, I'm using sale. I've never used create_payment_token before and am unfamiliar with this.
Have you tried with sale?
getUTCDateTime() - I had to hardcode something like this to account for time difference:
private static String getUTCDateTime() {
DateTime oUTSDateTime = System.now().addHours(-8);
String strUTCDateTime = oUTSDateTime.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'');
return strUTCDateTime;
}
Yes all you suggestions were an absolute hit and I am able to access this checkout page.
As per my code shared above
<form id="theForm" action="https://testsecureacceptance.cybersource.com/token/create"method="post">
HTML form is submitted and we get the checkout hosted page and payment is done, using tokenization. Goes well.
But I need the response from Cybersource, how to capture it in salesforce, since the response got the token information and that will be used for subsequent transactions, I have a public salesforce page linked to response url but I believe there has to be some altercations to it.
Any pointers....
No worries.
Again, I must share that I am not familiar with the token endpoint. In my use case, the user selected a payment to make in a table, pressed a button, and I post the form data to redirect them to the Cybersource gateway. Certain fields like email, last name, first name, amount and currency will be autofilled. User will key in their credit card details within Cybersource.
In my case, this was the endpoint I was posting the form data to: https://testsecureacceptance.cybersource.com/pay.
Subsequently within Cybersource, there are two settings to configure: Merchant Post URL and Customer Response Page.
For production-readiness, it is good to configure Merchant Post URL kind of as a backup for intermittent loss of network connection etc. But it should still work if the following steps are performed:
1. Create public site in Salesforce
2. Create a visualforce page which will be in this public site.
3. Configure the Customer Response Page to be the URL of this visualforce page hosted within the public site.
4. Within the visualforce page, the Apex controller will be responsible for parsing the response sent back from Cybersource. In the controller constructor, you would have access to these parameters through the ApexPages.currentPage().getParameters() method.
5. Using page action (because DML action is not allowed in Apex class constructor), I perform the necessary DML I need based on the instance variables of the class whose values are populated by the constructor.
You are amazing.
I was on track and did everything same as you mentioned (above 5 steps) what I did'nt do was to debug the ApexPages.currentPage().getParameters() .
Thanks again for your knowledge and taking me out of it.
I'm happy to share this because it took me forever to even get past authentication. The timestamp issue killed me for awhile. And the fact that the authentication mechanism for refund is different is another painful memory.
Coz I am able to do using 3DS 1.0 but need to have setup using 3DS 2.0 as well where user will be shown additional authentication but there is not really good help available in documentation.
I am trying to implement Cybersource Secure Hosted Checkout and facing 403(Access forbidden) error. I have followed your approach. Could you please let me know where I was wrong? Below is the code snippet thanks
VfPage:
<apex:page showHeader="false" controller="HostedCheckoutDemo_Controller" title="Payment gateway">
<apex:outputPanel id="testcard" >
<apex:define name="body" >
<center>
<!--form id="theForm" action="{!endp}" method="post"-->
<form id="theForm" action="https://testsecureacceptance.cybersource.com/token/create" method="post">
<apex:panelGrid columns="1" style="margin-top:1em;">
<apex:outputtext escape="false" value="{!ParametersValues}"/>
<!--<apex:outputtext escape="false" value="{!ParametersValuesHidden}"/>-->
<apex:outputtext escape="false" value="{!SignedData}" />
</apex:panelGrid>
<apex:panelGrid columns="2" style="margin-top:1em;">
<input type="submit" id="submit" value="Confirm "/>
</apex:panelGrid>
<br/>
</form>
</center>
</apex:define>
</apex:outputPanel>
</apex:page>
Controller:
public with sharing class HostedCheckoutDemo_Controller {
private Map<String,String> oPassedParams = new Map<String,String>();
public String ParametersValues = getParametersValues();
public String SignedData = getSignedData();
public static String sign(Map<string, string> paramsArray) {
String result = sign(buildDataToSign(paramsArray), HostedCheckoutDemo_Controller.recover());
System.debug('sign result'+result);
return result;
}
public String getUUID(){
Blob b = Crypto.generateAesKey(128);
String h = EncodingUtil.convertToHex(b);
String guid = h.substring(0,8) + '-' + h.substring(8,12) + '-' + h.substring(12,16) + '-' + h.substring(16,20) + '-' + h.substring(20);
return guid;
}
private static String getUTCDateTime() {
DateTime oUTSDateTime = System.now().addHours(-8);
String strUTCDateTime = oUTSDateTime.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'');
return strUTCDateTime;
}
public String getParametersValues(){
String result = '';
oPassedParams.put('access_key','*********'); //hard coded access key for now
oPassedParams.put('profile_id','************'); //hard coded profile ID for now
oPassedParams.put('transaction_uuid','02815b4f08e56882751a043839b7b481'); ////hard coded transaction ID for now
oPassedParams.put('signed' +
'_field_names','access_key,profile_id,transaction_uuid,signed_field_names,unsigned_field_names,' +
'signed_date_time,locale,transaction_type,reference_number,amount,currency,payment_method');
oPassedParams.put('unsigned_field_names','card_type,card_number,card_expiry_date');
oPassedParams.put('signed_date_time',getUTCDateTime());
oPassedParams.put('locale','en');
oPassedParams.put('transaction_type','create_payment_token');
oPassedParams.put('reference_number','2432432');
oPassedParams.put('amount','1.00');
oPassedParams.put('currency', 'usd');
oPassedParams.put('payment_method','card');
/*oPassedParams.put('bill_to_forename','sai');
oPassedParams.put('bill_to_surname', 'gan');
oPassedParams.put('bill_to_email','sai.repaka@8x8.com');
oPassedParams.put('bill_to_address_line1','gfdsgdfg');
oPassedParams.put('bill_to_address_city','dfgsgsd');
oPassedParams.put('bill_to_address_postal_code', '12345');
oPassedParams.put('bill_to_address_state','ca');
oPassedParams.put('bill_to_address_country','usa');
oPassedParams.put('card_type','001');
oPassedParams.put('card_number', '4111111111111111');
oPassedParams.put('card_cvn','005');*/
for (String oKey : oPassedParams.KeySet()){
result += '<div>';
result += '<input type="hidden" id="' + oKey + '" name="' + oKey + '" value="' + oPassedParams.get(oKey) + '"/>';
result += '</div>';
}
system.debug('--ParametersValues' +result);
return result;
}
/*public String getParametersValuesHidden(){
String result = '';
for (String oKey : oPassedParams.KeySet()){
result += '<input type="hidden" id="' + oKey + '" name="' + oKey + '" value="' + oPassedParams.get(oKey) + '"/>';
}
system.debug('--ParametersValuesHidden' + result);
return result;
}*/
public String getSignedData(){
String result = '';
result += '<input type="hidden" id="signature" name="signature" value="' + HostedCheckoutDemo_Controller.sign(oPassedParams) + '"/>';
system.debug('-- getSignedData' + result);
return result;
}
private Static String recover(){
return '**************';
}
private static String commaSeparate(List<string> dataToSign) {
String result = '';
for(String Str : dataToSign) {
result += (result==''?'':',')+Str;
}
return result;
}
private static String buildDataToSign(Map<string,string> paramsArray) {
String[] signedFieldNames = paramsArray.get('signed_field_names').Split(',');
List<string> dataToSign = new List<string>();
for (String oSignedFieldName : signedFieldNames){
dataToSign.Add(oSignedFieldName + '=' + paramsArray.get(oSignedFieldName));
}
return commaSeparate(dataToSign);
}
private static String sign(String data, String secretKey) {
String result = EncodingUtil.base64Encode(Crypto.generateMac('hmacSHA256', Blob.valueOf(data), Blob.valueOf(secretKey)));
return result;
}
}
I have previously coded the cybersource payment functionality in .NET and it works fine. Now I need to move it to salesforce. I created a VF page form with amount and 2 custom fields. I followed the exact steps outlined in your code and I am getting the "You are not authorized to view this page. The transaction has not been processed". I was told by cybersource that it could be: access_key, security_key, missing signed-values, missing required fields and incorrect signed_date_time_stamp. I don't think any of them are valid in my case. I changed the signed_date_time_stamp value but it does not seem to work. I am in EST and behind UTC by 4 hours, I even tried: dateTime.now()-4,dateTime.now()+4, dateTime.now() etc but nothing works.
Whan am I missing ??
Here is the error from the server: Request Processing Error - Reference: [E-C15017F3DD7E484EBD918CAFE5B0F605] Exception Class: [TransactionSecurityError] Exception Message: [Merchant supplied signature does not match generated signature] Here are some things you should check. Some things the merchant should check: - Invalid/Missing Merchant ID - Blank, or greater than thirty (30) characters in length - Invalid/Missing Profile ID - Blank, or less than seven (7) characters in length - Can be any value; no longer a required field - Invalid/Missing/Expired Secret and/or Access Key - Supplied signature does not match the generated one - The supplied signed_field_name parameter value is missing a mandatory signed_field - An empty field name (,,) was in the supplied signed_field_name or unsigned_field_name parameter values - The supplied signed_date_time parameter value was not in a valid UTC xml format (end in Z)
The approach followed by me was cybersource secure acceptance hosted payment page (HPP) which make use of http post and passing all the relevant information to cybersource for authorization and verification.
I will suggest you two approaches :
1. In your case it seems to me your request is getting failed at first step itself that is the authorization during which a signature is created using the values that you send and same siganture is validated by cybsersource.
The response from cybersource is right , you need to check for the following values as they are indeed cross verified by cybersource and is needed in signature generation :
a. Access key
b. Profile id
c. Security recovery key
2. Keep your code as it is since you mentioned it was working with .NET and try with this syntax for UTC timezone -
System.now().addHours(4)
I hope above information helps you and it works smoothly.
Your Department/Division/Unit:
Comments:
Controller public class Payment_Controller_Cybersource { private Map oPassedParams = new Map(); public String amount {get;set;} public static String sign(Map paramsArray) { String result = sign(buildDataToSign(paramsArray), Payment_Controller_Cybersource.recover()); return result; } public String getUUID(){ Blob b = Crypto.generateAesKey(128); String h = EncodingUtil.convertToHex(b); String guid = h.substring(0,8) + '-' + h.substring(8,12) + '-' + h.substring(12,16) + '-' + h.substring(16,20) + '-' + h.substring(20); return guid; } public static String getUTCDateTime() { //datetime oUTSDateTime = datetime.now(); datetime oUTSDateTime = System.now().addHours(4); String strUTCDateTime = oUTSDateTime.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\''); return strUTCDateTime; } public String getParametersValues(){ String result = ''; oPassedParams.put('access_key','xxxx'); oPassedParams.put('profile_id','xxxx'); oPassedParams.put('transaction_uuid',getUUID()); oPassedParams.put('signed_field_names','access_key,profile_id,transaction_uuid,signed_field_names,unsigned_field_names,signed_date_time,locale,transaction_type,reference_number,amount,currency, payment_method'); oPassedParams.put('unsigned_field_names','merchant_defined_data1,merchant_defined_data2'); oPassedParams.put('signed_date_time',getUTCDateTime()); oPassedParams.put('locale','en-us'); oPassedParams.put('transaction_type','sale'); oPassedParams.put('reference_number','100'); oPassedParams.put('amount',amount); oPassedParams.put('currency', 'USD'); oPassedParams.put('payment_method','card'); for (String oKey : oPassedParams.KeySet()){ result += '
Visualforce Page
<apex:page showHeader="false" controller="Payment_Controller_Cybersource" title="Payment gateway">
<apex:outputPanel id="testcard">
<apex:define name="body">
<center>
<form id="theForm" action="https://secureacceptance.cybersource.com/pay" method="post">
<apex:panelGrid columns="1" style="margin-top:1em;">
<apex:outputtext escape="false" value="{!ParametersValues}"/>
<apex:outputtext escape="false" value="{!ParametersValuesHidden}" />
<apex:outputtext escape="false" value="{!SignedData}" />
</apex:panelGrid>
<apex:panelGrid columns="2" style="margin-top:1em;">
<span>Amount to charge :</span><input type="text" name="amount" /><br/>
<span><b>Your Department/Division/Unit:</b></span><input type="text" name="merchant_defined_data1" /><br/>
<span><b>Comments:</b></span><input type="text" name="merchant_defined_data2" /><br/>
<input type="submit" id="submit" value="Confirm "/>
</apex:panelGrid>
<br/>
</form>
</center>
</apex:define>
</apex:outputPanel>
</apex:page>
Controller
public class Payment_Controller_Cybersource {
private Map<String,String> oPassedParams = new Map<String,String>();
public String amount {get;set;}
public static String sign(Map<string, string> paramsArray) {
String result = sign(buildDataToSign(paramsArray), Payment_Controller_Cybersource.recover());
return result;
}
public String getUUID(){
Blob b = Crypto.generateAesKey(128);
String h = EncodingUtil.convertToHex(b);
String guid = h.substring(0,8) + '-' + h.substring(8,12) + '-' + h.substring(12,16) + '-' + h.substring(16,20) + '-' + h.substring(20);
return guid;
}
public static String getUTCDateTime() {
//datetime oUTSDateTime = datetime.now();
datetime oUTSDateTime = System.now().addHours(4);
String strUTCDateTime = oUTSDateTime.format('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'');
return strUTCDateTime;
}
public String getParametersValues(){
String result = '';
oPassedParams.put('access_key','xxxx');
oPassedParams.put('profile_id','xxxx');
oPassedParams.put('transaction_uuid',getUUID()); oPassedParams.put('signed_field_names','access_key,profile_id,transaction_uuid,signed_field_names,unsigned_field_names,signed_date_time,locale,transaction_type,reference_number,amount,currency, payment_method');
oPassedParams.put('unsigned_field_names','merchant_defined_data1,merchant_defined_data2');
oPassedParams.put('signed_date_time',getUTCDateTime());
oPassedParams.put('locale','en-us');
oPassedParams.put('transaction_type','sale');
oPassedParams.put('reference_number','100');
oPassedParams.put('amount',amount);
oPassedParams.put('currency', 'USD');
oPassedParams.put('payment_method','card');
for (String oKey : oPassedParams.KeySet()){
result += '<div>';
result += '<input type="hidden" id="' + oKey + '" name="' + oKey + '" value="' + oPassedParams.get(oKey) + '"/>';
result += '</div>';
}
system.debug('--ParametersValues' +result);
return result;
}
public String getParametersValuesHidden(){
String result = '';
for (String oKey : oPassedParams.KeySet()){
result += '<input type="hidden" id="' + oKey + '" name="' + oKey + '" value="' + oPassedParams.get(oKey) + '"/>';
}
system.debug('--ParametersValuesHidden' + result);
return result;
}
public String getSignedData(){
String result = '';
result += '<input type="hidden" id="signature" name="signature" value="' + Payment_Controller_Cybersource.sign(oPassedParams) + '"/>';
system.debug('-- getSignedData' + result);
return result;
}
private Static String recover(){
string ss='xxxx'; //secret key
return ss;
}
private static String commaSeparate(List<string> dataToSign) {
String result = '';
for(String Str : dataToSign) {
result += (result==''?'':',')+Str;
}
return result;
}
private static String buildDataToSign(Map<string,string> paramsArray) {
String[] signedFieldNames = paramsArray.get('signed_field_names').Split(',');
List<string> dataToSign = new List<string>();
for (String oSignedFieldName : signedFieldNames){
dataToSign.Add(oSignedFieldName + '=' + paramsArray.get(oSignedFieldName));
}
return commaSeparate(dataToSign);
}
private static String sign(String data, String secretKey) {
String result = EncodingUtil.base64Encode(Crypto.generateMac('hmacSHA256', Blob.valueOf(data), Blob.valueOf(secretKey)));
return result;
}
}
Can you set hard coded value for amount as of now, and see the outcome.
oPassedParams.put('amount','111');
2. Have you configured secure acceptance HPP profile correctly in your cybersource environment.
I tried hard-coding amount and pointing end point to test. Both don't work.
I have not changed the secure acceptance HPP profile as my current .NET payment site is working as expected. I am only setting value for this
Custom Redirect After Checkout and this should not matter as I am not saving any return values from the postback.
Originally when I set this up in .NET, it was very quick and easy but there seems to be something wrong in my apex code with the response values that's causing the error.
I sent the error code to cybersource and they told me to fix the payment_method since I was not sending that value. There was an extra space in the signed_field_names before the payment_method. I fixed that and got the error again. I sent the error to cybersource and here's their response:
The error code you submitted returned the following error from our server: Request Processing Error - Reference: [E-A308FA76B66C4A7C81A02A2839BE78A3] Exception Class: [TransactionSecurityError] Exception Message: [Merchant supplied signature hqxc6SIZs7caWZQmjF3M4SekBM2tWkgtGd2oe66ABc8= does not match generated signature 9YH7MtzWLhIMNzFsxnBcvVbItm4uOFo7W7IUDxgv440=] Please note, this error is the result of the merchant application creating a signature that is different from the system generated signature. This can only be resolved by correcting the merchant application. We haven't any more information than I have provided in the above error message since we cannot reverse the signature to see what fields do not match. This will require your team to study your application to identify the fields that are incorrect and edit them.
Just realized I was passing the merchant_id (6 digit) vs the 36 digit profile_id for the Profile_id request field. I fixed my code but still get the same error
My issue is resolved. The sample code provided here creates the signature before I enter the amount. The amount will never match with the amount in the signature. I had to capture the amount and then create the signature with the amount before posting to cybersource.
Thanks for the help
Just when I thought I had all of this wrapped up, another issue has come up. I was able to get to the hosted payment page from my visualforce page by clicking the preview button.
I then created a public force.com site and added the visualforce page to the site. When I go through the sites page, I get the same error as before:
"You are not authorized to view this page. The transaction has not been processed".
Any idea what's different about the force.com site page access
For guys out there needing help with cybersource integration, please do not hesitate to contact me. I learned a lot from this.
Hi Everyone
Can anyone share the working code for payment checkout for this Cybersource. I tried with the above code of Vipul, Tom, and Venkat but it is still showing below error
"You are not authorized to view this page. The transaction has not been processed.
If the problem persists please report your problem and quote the following Error Reference Number:
E-01C08E972C6D4A1485712ED822A91AEA"
Any help will be highly appreciated.