Get Paypal parameters in cancel_return - paypal

I want to get a parameter from Paypal which I am sending in 'custom' named hidden field. I can get the same on success page but not in cancel page. Does it need some efforts or Paypal do not provide any value on cancel page?

Which language are you using to Integrate paypal?
I am using Java application. And I can tell you how I have approached this one. And I used Paypal Payments Pro Hosted Checkout solution. I guess you are using the same too.
Logging into the manager paypal account, we can actually configure the Success, Failure and Cancel url.
For example let us say the below are the urls we have configured
paySuccessUrl = "http://mywebsite.com/ecommerce/paySuccess.htm";
payFailureUrl = "http://mywebsite.com/ecommerce/payFailure.htm";
payCancelUrl = "http://mywebsite.com/ecommerce/payFailure.htm";
We can only have one url for success, one for failure and one for cancel. But actually since the user can initiate payment transaction in various pages, it will be difficult for us to have only one single url per status.
So to approach this, I put the urls in the Java Session object.
For example : if user is in page a and initiated a payment transaction , what I typically do is
url a : http://mywebsite.com/ecommerce/a.htm
String successUrl = "http://mywebsite.com/eccommerce/successA.htm";
String failureUrl = "http://mywebsite.com/ecommerce/failureA.htm";
String cancelUrl = "http://mywebiste.com/ecommerce/cancelA.htm";
// Here append as many no of parameters as you wish
Example : cancelUrl = cancelUrl + "prm1=" + val1 + "&par2=" + val2;
For url b
// url b : http://mywebsite.com/ecommerce/b.htm
// String successUrl = "http://mywebsite.com/eccommerce/successB.htm";
// String failureUrl = "http://mywebsite.com/ecommerce/failureB.htm";
// String cancelUrl = "http://mywebiste.com/ecommerce/cancelB.htm";
HttpSessionn session = (HttpSession)request.getSession(true);
session.setAttribute("successUrl", successUrl);
session.setAttribute("failureUrl", failureUrl);
session.setAttribute("cancelUrl", cancelUrl);
So if pay is success
#RequestMapping("paySuccess.htm")
public void paySuccess(HttpServletRequest request, HttpServletResponse response) {
// Do some processing
HttpSession session = (HttpSession) request.getSession(true);
String successUrl = (String) session.getAttribute("successUrl");
response.sendRedirect(successUrl);
// which intern call "http://mywebsite.com/eccommerce/successA.htm" url
// or "http://mywebsite.com/eccommerce/successB.htm"
}
So if pay is failed then
#RequestMapping("payFailure.htm")
public void paySuccess(HttpServletRequest request, HttpServletResponse response) {
// Do some processing
HttpSession session = (HttpSession) request.getSession(true);
String failureUrl = (String) session.getAttribute("failureUrl");
response.sendRedirect(failureUrl);
// which intern call "http://mywebsite.com/eccommerce/failureA.htm" url
// or "http://mywebsite.com/eccommerce/failureB.htm"
}
And similarly for the pay cancel url
#RequestMapping("payCancel.htm")
public void paySuccess(HttpServletRequest request, HttpServletResponse response) {
// Do some processing
HttpSession session = (HttpSession) request.getSession(true);
String cancelUrl = (String) session.getAttribute("cancelUrl");
response.sendRedirect(cancelUrl);
// which intern call "http://mywebsite.com/eccommerce/cancelA.htm" url
// or "http://mywebsite.com/eccommerce/cancelB.htm"
}
So this way you don't need to send any custom parameters to paypal and expect paypal to send them back.
You can have your own cacel url in the session object with as many number of parameters appended as you wish.
I hope this helps you.

Related

Send Money to Paypal Account ASP.Net Server Side Code

I am having a difficult time finding halfway descent documentation or examples on how to send money to another Paypal account.
I have installed the Nuget package PaypalSDK version 1.0.4. I have read the documentation at https://developer.paypal.com/home. I have browsed and tried to implement the sample code at https://github.com/paypal/Checkout-NET-SDK.
The problem I am having is that I am having is that I am not seeing notifications of payments sent or received in my sandbox account. I can successfully execute a checkout with the Javascript button in my shopping cart view. But eventually I want to add the capability to send money from my Paypal business account to another Paypal business account, without the other Paypal Business Account owner having to be logged in to my website.
Does the money recipient have to authorize the money I send, or should it just get deposited into their account once I send it?
Here is my code:
namespace MyShoppingCart.Helpers.Paypal
{
public class CaptureOrderSample
{
static string PayPalClientID = Startup.StaticConfig.GetValue<string>("Paypal:ClientID");
static string PayPalClientSecret = Startup.StaticConfig.GetValue<string>("Paypal:ClientSecret");
public static HttpClient client()
{
// Creating a sandbox environment
PayPalEnvironment environment = new SandboxEnvironment(PayPalClientID, PayPalClientSecret);
// Creating a client for the environment
PayPalHttpClient client = new PayPalHttpClient(environment);
return client;
}
public async static Task<HttpResponse> createOrder(string Email)
{
HttpResponse response;
// Construct a request object and set desired parameters
// Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
var order = new OrderRequest()
{
CheckoutPaymentIntent = "CAPTURE",
PurchaseUnits = new List<PurchaseUnitRequest>()
{
new PurchaseUnitRequest()
{
AmountWithBreakdown = new AmountWithBreakdown()
{
CurrencyCode = "USD",
Value = "100.00"
},
Payee = new Payee
{
Email = Email // "payee#email.com"
}
}
}
//,
//ApplicationContext = new ApplicationContext()
//{
// ReturnUrl = "https://www.example.com",
// CancelUrl = "https://www.example.com"
//}
};
// Call API with your client and get a response for your call
var request = new OrdersCreateRequest();
request.Prefer("return=representation");
request.RequestBody(order);
response = await client().Execute(request);
var statusCode = response.StatusCode;
Order result = response.Result<Order>();
Debug.WriteLine($"Status: {result.Status}");
Debug.WriteLine($"Order Id: {result.Id}");
Debug.WriteLine($"Intent: {result.CheckoutPaymentIntent}");
Debug.WriteLine("Links:");
foreach (LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: { link.Method}");
}
return response;
}
}
}
And this is currently called from my Orders controller when an order is completed. This is just for testing purposes.
[Authorize]
public async Task<IActionResult> CompleteOrder()
{
var items = _shoppingCart.GetShoppingCartItems();
Models.Order order = await _ordersService.StoreOrderAsync(items);
PrepareSellerEmail(items, order, "You Have a New Order!");
PrepareBuyerEmail(items, order, "Thank You for Your Order!");
await _shoppingCart.ClearShoppingCartAsync(_serviceProvider);
DeleteCartIDCookie();
//OrderRequest request = Helpers.CreateOrderSample.BuildRequestBody("USD", "100.00", "sb-r43z1e9186231#business.example.com");
//var client = Helpers.Paypal.CaptureOrderSample.client();
var result = Helpers.Paypal.CaptureOrderSample.createOrder("sb-r43z1e9186231#business.example.com");
//var response = await PayPalClient.client().execute.(request);
return View("OrderCompleted");
}
The output of the result is:
Status: CREATED
Order Id: 51577255GE4475222
Intent: CAPTURE
Links:
self: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: GET
approve: https://www.sandbox.paypal.com/checkoutnow?token=51577255GE4475222 Call Type: GET
update: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222 Call Type: PATCH
capture: https://api.sandbox.paypal.com/v2/checkout/orders/51577255GE4475222/capture Call Type: POST
This is a screen capture from my sandbox account:
Am I supposed to do something else to actually execute the transfer?
Edit: I figured out how to use the Paypal Payouts API.
First I installed the Nuget Package. It's simply called PayoutsSdk. I'm using version 1.1.1.
For the payout to execute, you need the client() method that is listed above in this post, and this CreatePayout() method listed below.
public async static Task<HttpResponse> CreatePayout()
{
var body = new CreatePayoutRequest()
{
SenderBatchHeader = new SenderBatchHeader()
{
EmailMessage = "Congrats on recieving 1$",
EmailSubject = "You recieved a payout!!"
},
Items = new List<PayoutItem>()
{
new PayoutItem()
{
RecipientType="EMAIL",
Amount=new Currency()
{
CurrencyCode="USD",
Value="1",
},
Receiver="sb-r43z1e9186231#business.example.com",
}
}
};
PayoutsPostRequest request = new PayoutsPostRequest();
request.RequestBody(body);
var response = await client().Execute(request);
var result = response.Result<CreatePayoutResponse>();
Debug.WriteLine($"Status: {result.BatchHeader.BatchStatus}");
Debug.WriteLine($"Batch Id: {result.BatchHeader.PayoutBatchId}");
Debug.WriteLine("Links:");
foreach (PayoutsSdk.Payouts.LinkDescription link in result.Links)
{
Debug.WriteLine($"\t{link.Rel}: {link.Href}\tCall Type: {link.Method}");
}
return response;
}
Of course I'll add parameters to the method for email, amount, currency code, email message, and subject.
Right now, I am calling this method from the controller method like this: var result = Helpers.Paypal.CaptureOrderSample.CreatePayout(); where Helpers.Paypal are folders that contain a class called CaptureOrderSample, which I will probably rename.
To send money from your account to another account, there are several different options:
Automate the sending with the Payouts API or Payouts Web (spreadsheet upload). For live, payouts can only be used if the live account sending the payment is approved for payouts.
Log into the account that is going to send the money in https://www.paypal.com or https://www.sandbox.paypal.com and click on the menu for Pay & Get Paid -> Send Money .
Use a PayPal Checkout integration, with or without the Orders API, and specify a payee that is to receive the money. You must log in with the paying (sending) account to approve the sending, and finally the order must be captured (via API or client side actions.order.capture()) which is what results in a PayPal transaction. If the final capture step is not performed, no money will be sent and the order will merely remain created or approved and eventually expire (72 hours after creation or 3 hours after approval)
In the sandbox, no actual emails are sent with notifications. Instead, the developer.paypal.com dashboard has a "Notifications" tab on the left, and of course activity will also be visible in each sandbox account by logging into the account. Only captured activity is likely to be visible.

Callback function issues in FB.API for Unity

I am using Unity 5.5.2f1 pro and facebook's SDK v 7.9.4
I have a script which after login (managed in a previous scene) sends an API request to FB asking for friends, name and email and sends that info as a POST to a php website.
code:
[Serializable]
public struct FBData {
public string first_name;
public string email;
public string friends;
public string id;}
public class UserManagement : MonoBehaviour {
string urlSaveUserData="some php website";
public Text testTxt;
FBData parsedData;
// Use this for initialization
void Start () {
//Check if it's the first time the user is opening the app.
if (UserInfo.FIRST_TIME) {
//update text (only used for testing, should be removed in production.)
testTxt.text = "Your user id is: " + UserInfo.ID;
//Perform FB.API call to get User Data.
getUserData ();
//Save in SQL table. (won't get here if line in getUserData() is active)
StartCoroutine ("saveUserData");
} else {
//do something else.
}
note: Since this is meant for iOS I have to test it on a device so I'm using text in the screen to display info (think of it as a badly implemented print statement).
The problem: In my callback function for FB.API I write in the text Gameobject (aka testTxt) the parsed information from the response which is saved in the Custom UserInfo clss. It display's correctly but the code gets stuck there. It doesn't continue to the next function. HOWEVER, if I delete/comment that line and don't display anything in the text field. The codes does continue to the POST function BUT the information from the API call is not passed, i.e my custom class is empty (leading me to believe the callback function is not called at all).
public void getUserData(){
string query = "me?fields=first_name,email,friends";
FB.API (query, HttpMethod.GET, Apicallback, new Dictionary<string, string> ());
}
private void Apicallback(IGraphResult result){
//Parse Graph response into a specific class created for this result.
parsedData = JsonUtility.FromJson<FBData>(result.RawResult);
//Pass each field into UserInfo class.
UserInfo.EMAIL = parsedData.email;
UserInfo.FRIENDS = parsedData.friends;
UserInfo.NAME = parsedData.first_name;
UserInfo.FACEBOOKID = parsedData.id;
/*problem area, if I comment line below, then previous information is apparently not stored. If left as is then testTxt displays correct information but code gets stuck there. */
testTxt.text = "This is the info from USerInfoInside the APICallback: " + UserInfo.EMAIL + UserInfo.FRIENDS + UserInfo.FACEBOOKID;
}
The function below is to send info to php website, is there for illustrative purposes:
code:
public IEnumerator saveUserData() {
//get user info (this information is EMPTY if line in getUserData() is commented.
parsedData.id = UserInfo.FACEBOOKID;
parsedData.friends = UserInfo.FRIENDS;
parsedData.first_name = UserInfo.NAME;
parsedData.email = UserInfo.EMAIL;
//translate data into json
string JsonBodyData = JsonUtility.ToJson (parsedData);
//Custom web request (POST method doesnt seem to work very well, documentation example sends empty form)
var w = new UnityWebRequest(urlSaveUserData, "POST");
byte[] bodyRaw = new System.Text.UTF8Encoding().GetBytes(JsonBodyData);
w.uploadHandler = (UploadHandler) new UploadHandlerRaw(bodyRaw);
w.downloadHandler = (DownloadHandler) new DownloadHandlerBuffer();
w.SetRequestHeader("Content-Type", "application/json");
yield return w.Send();
//work with received data...}
Im stuck here any help is appreciated. Thanks!
Be sure to use EscapeURL when using strings directly for JSON or HTTP POST and GET methods. The lack of this treatment tends to screw things over, particulary in iOS platforms.
From what I can see, this code
string query = "me?fields=first_name,email,friends";
should instead be escaped as
string query = WWW.EscapeURL("me?fields=first_name,email,friends");
so characters like "?" won't get encoded as an URL symbol.
I'm assuming you don't need to do that for your illustrative example, because UnityWebRequest already escapes your POST request strings internally, but I can't fully confirm that.

Integrating with PayPal with no web site

I was thinking about integration in the background without any website other than the payment page as part of a desktop application in c++.
Would it be possible to following the following scenario:
1. Generate the invoice / sale and via REST API obtain some sort of unique ID for the transaction to come.
2. Redirect to Paypal web site to a ad-hoc payment page, using the unique ID.
3. In the background, check every few minutes, via REST API, if the payment was made.
We finally found a way, which is why I publish this answer along with some code (a POC) we have developed. This is a POC for a built-in payment processing engine which allows you to accept payments from any credit card holder (regardless of being a PayPal customer) and pay for unlocking a software product or for specific features.
To process payments you need to apply as a PayPal developer and obtain your own PayPal credentials. You will then receive 2 sets of credentials. One for tests ("sandbox") and the other for real life.
First you can use the Sandbox to test the API
Void InitPayPal(BOOL Sandbox, LPTSTR User, LPTSTR password, LPTSTR signature, LPTSTR successUrl, LPTSTR failedURL)
Sandbox – indicates whether you are testing your integration using PayPal's Sandbox account, or going live.
User – your PayPal user name
Password – your PayPal password
Signature – you PayPal signature
successUrl – a url leading to a web page which you wish to be shown after successful payment.
failedURL – a url leading to a web page which you wish to be shown after failed / cancalled payment.
This function is straight forward:
void InitPayPal(BOOL Sandbox, LPTSTR User, LPTSTR password, LPTSTR signature, LPTSTR successUrl, LPTSTR failedURL, LPWSTR ProductName)
{
m_sandbox = Sandbox;
m_user = User;
m_password = password;
m_signature = signature;
m_SuccessURL = successUrl;
m_FailureURL = failedURL;
m_ProductName = ProductName;
CUR_CHAR = L"$";
SYSTEMTIME st;
GetSystemTime(&st);
g_tPayStart = CTime(st);
InitilizedPaypal = TRUE;
}
Initiating a payment
When you wish to initiate a payment from your program, you call the following function which I wrote which generally build a string (ExpChkoutStr) and use the following PayPal API call:
// Send string to PayPal server
WinHttpClient WinClient1(ExpChkoutStr.GetBuffer());
WinClient1.SetRequireValidSslCertificates(false);
WinClient1.SendHttpRequest(L"GET");
httpResponseContent1 = WinClient1.GetResponseContent();
CString strTransactionRet = UrlDecode(httpResponseContent1.c_str());
The WinHTTP class was developed by Cheng Shi.
The Express Checkout String (ExpChkoutStr) is generated by another function which uses the member variables' values and the transaction details into a single string:
CString result;
result = (m_sandbox) ? PAYPAL_SANDBOX_HTTPS : PAYPAL_REAL_HTTPS;
result += Q_USER;
result += m_user;
result += AND_PASSWORD;
result += m_password;
result += AND_SIGNATURE;
result += m_signature;
result += AND_PAYMENTAMOUNT;
result += strAmount;
result += L"&METHOD=SetExpressCheckout";
result += AND_RETURN_URL;
result += m_SuccessURL;
result += AND_CANCEL_URL;
result += m_FailureURL;
result += AND_VERSION;
result += L"&NOSHIPPING=1";
result += L"&ADDROVERRIDE=0&BRANDNAME=Secured Globe, Inc.";
result += L"&PAYMENTREQUEST_0_DESC=";
result += L"Item name: " + strUnits + L"(" + UnitName + L") ";
result += L"Price: " + strAmount;
result += L"&NOTETOBUYER=Here you can add a note to the buyer";
The result from the PayPal server is a "token" used to figure out a one-time web page (LinkToOpen ) that must be opened in order for the end user to confirm the purchase:
// Extract token from response
CString sToken = ExtractElement(strTransactionRet, L"TOKEN");
if (sToken == L"")
{
wprintf(L"Internal error: (Paypal): no token was generated (%s)", strTransactionRet);
MessageBox(NULL, L"Internal payment processing error", L"", MB_OK);
return FALSE;
}
CString LinkToOpen = (m_sandbox) ? SANDBOX_PAYPAL_CHECKOUT : REAL_PAYPAL_CHECKOUT;
LinkToOpen += L"&token=";
LinkToOpen += sToken;
We then programatically open this one-time web page using the default web browser:
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CString command_line;
command_line.Format(L"cmd.exe /c start \"link\" \"%s\" ", LinkToOpen);
// LinkToOpen
if (!CreateProcess(NULL, // No module name (use command line)
command_line.GetBuffer(),
NULL, // Process handle not inheritable
NULL, // Thread handle not inhberitable
FALSE, // Set handle inheritance to FALSE
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi) // Pointer to PROCESS_INFORMATION structure
)
{
wprintf(L"CreateProcess failed (%d).\n", GetLastError());
// At this stage you would want to mark this transaction as "failed"
return FALSE;
}
Then the rest is to maintain a small database of all pending transactions and follow up each of them until it is either succeed, failed, cancelled or if a timeout has passed.
To extract elements from the PayPal server response, we wrote this small function:
CString ExtractElement(CString EntireString, CString ElementName)
{
CString result = L"";
CString WhatToFind = ElementName + L"=";
int foundToken = EntireString.Find(WhatToFind);
if (foundToken > -1)
{
int EndToken = EntireString.Find(L"&", foundToken);
if (EndToken != -1)
{
result = EntireString.Mid(foundToken + ElementName.GetLength()+1, EndToken - foundToken - ElementName.GetLength()-1);
}
}
return result;
}

How to call Windows Azure Storage RestFul Service without SDK?

I try to use Windows Azure like a Storage fom Salesforce.com.
I cheked the documentation and I only can see call the calls to azure rest api from SDK (Java, .Net, JS, etc) examples.
I need integrate Salesforce with Windows Azure Storage but, Azure don't have a SDK for Salesforce.com
From Salesforce.com is allow the calls to rest services but the process to call Azure Rest Services require one o more librarys.
Exameple:
Authentication for the Azure Storage Services require of:
Headers: Date Header and Authorization Header
The Authorization Header require two elments
SharedKey
Account Name
Authorization="[SharedKey|SharedKeyLite] :"
SharedKey and Account Name give a conversion:
HMAC-SHA256 conversion
over UTF-8 encoded
For this convertion the documentation referes to SDK Librarys in others words Java Class or .Net Class type helper that in Salesforce.com not exist.
Please, I need a example to call the authentification service without sdk
Sorry for my bad English.
Visit: https://learn.microsoft.com/en-us/rest/api/storageservices/fileservices/authentication-for-the-azure-storage-services
I need a example to call the authentification service without sdk
We could generate signature string and specify Authorization header for the request of performing Azure storage services without installing SDK. Here is a simple working sample to list the containers, you could refer to my generateAuthorizationHeader function and Authentication for the Azure Storage Services to construct the signature string.
string StorageAccount = "mystorageaccount";
string StorageKey = "my storage key";
string requestMethod = "GET";
string mxdate = "";
string storageServiceVersion = "2014-02-14";
protected void btnlist_Click(object sender, EventArgs e)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(string.Format(CultureInfo.InvariantCulture,
"https://{0}.blob.core.windows.net/?comp=list",
StorageAccount
));
req.Method = requestMethod;
//specify request header
string AuthorizationHeader = generateAuthorizationHeader();
req.Headers.Add("Authorization", AuthorizationHeader);
req.Headers.Add("x-ms-date", mxdate);
req.Headers.Add("x-ms-version", storageServiceVersion);
using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
{
var stream = response.GetResponseStream();
StreamReader reader = new StreamReader(stream);
string content = reader.ReadToEnd();
StringReader theReader = new StringReader(content);
DataSet theDataSet = new DataSet();
theDataSet.ReadXml(theReader);
DataTable dt = theDataSet.Tables[2];
}
}
public string generateAuthorizationHeader()
{
mxdate = DateTime.UtcNow.ToString("R");
string canonicalizedHeaders = string.Format(
"x-ms-date:{0}\nx-ms-version:{1}",
mxdate,
storageServiceVersion);
string canonicalizedResource = string.Format("/{0}/\ncomp:list", StorageAccount);
string stringToSign = string.Format(
"{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}",
requestMethod,
canonicalizedHeaders,
canonicalizedResource);
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(StorageKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
String authorization = String.Format("{0} {1}:{2}",
"SharedKey",
StorageAccount,
signature
);
return authorization;
}
Besides, please refer to Azure Storage Services REST API Reference to know more about programmatic access to Azure Storage Services via REST APIs.
I find a way to solve this.
You should use Shared Sing, here explain me:
Enter to Portal Azure
Open the Account Storage
In the General Information click on "Share sing access"
Enable all permissions that you need (In my case only Enable "File")
Enable all resources permission that you need (In my case onl Enable "Service, Container and Object")
Define and Start Date and End Date (This is the space of time that Shared Key will be valid)
Define protocol type (In my case use HTTPS)
Clic on "Generate SAS" button
After this process you will get a token like this:
?sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-11-28T04:29:49Z&st=2017-02-18T20:29:49Z&spr=https&sig=rt7Loxo1MHGJqp0F6ryLhYAmOdRreyiYT418ybDN2OI%3D
You have to use this Token like Autentication
Example Call Code List a Content:
public with sharing class CallAzureRestDemo {
public string token = '&sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-02-19T04:00:44Z&st=2017-02-18T20:00:44Z&spr=https&sig=GTWGQc5GOAvQ0BIMxMbwUpgag5AmUVjrfZc56nHkhjI%3D';
//public Integer batchSize;
public CallAzureRestDemo(){}
public void getlistcontent(String endpoint)
{
// Create HTTP GET request
HttpRequest req = new HttpRequest();
req.setMethod('GET');
req.setEndpoint(endpoint+token);
Http http = new Http();
HTTPResponse res;
System.debug(LoggingLevel.INFO, '##RESPONSE: '+res);
// only do this if not running in a test method
if(!Test.isRunningTest())
{
System.debug(LoggingLevel.INFO, 'Sending the message to Azure');
res = http.send(req);
System.debug(LoggingLevel.INFO, 'http.send result status: ' + res.getStatus());
}
else
{
System.debug(LoggingLevel.INFO, 'Running in a test so not sending the message to Azure');
}
}
}
Example TestMethod:
#isTest
private class Test_CallAzureRestDemo {
static testMethod void myUnitTest() {
CallAzureRestDemo oRest = new CallAzureRestDemo();
try{
//Call the method and set endpoint
oRest.getlistcontent('https://accountstoragecomex.file.core.windows.net/?comp=list');
}catch(Exception e){
System.debug('##'+e);
}
}
}
Example to Response:
20:15:47.64 (79388244)|CALLOUT_REQUEST|[100]|System.HttpRequest[Endpoint=https://accountstoragecomex.file.core.windows.net/?comp=list&sv=2016-05-31&ss=f&srt=sco&sp=rwdlc&se=2017-02-19T04:00:44Z&st=2017-02-18T20:00:44Z&spr=https&sig=GTWGQc5GOAvQ0BIMxMbwUpgag5AmUVjrfZc56nHkhjI%3D, Method=GET]
20:15:47.64 (395755012)|CALLOUT_RESPONSE|[100]|System.HttpResponse[Status=OK, StatusCode=200]
Example Call Service "FILE - Get List Share"
Call To List Content
One more time, Sorry for my bad english.

Payflow Gateway w/ Secure Token & Transparent Redirect - return URL issue

I've built a client (in .NET, but it could be in any framework) to consume the Payflow Gateway NVP API using the Transparent Redirect and Secure Token features. I am able to receive the token, send the credit card data, and receive an Approved response from PayPal. The problem is that PayPal is not redirecting properly back to my site. I passed a RETURNURL (http://localhost:49881/transaction/details?processor=PayflowGateway) parameter when requesting the Secure Token, but instead of returning me to that URL after the transaction, it navigates my browser to the following URL:
https://pilot-payflowlink.paypal.com/http%3A%2F%2Flocalhost%3A49881%2Ftransaction%2Fdetails%3Fprocessor%3DPayflowGateway?POSTFPSMSG=No%20Rules%20Triggered&RESPMSG=Approved&ACCT=1111&COUNTRY=US&PROCCVV2=M&VISACARDLEVEL=12&CVV2MATCH=Y&CARDTYPE=0&PNREF=A70A8EB8B6A1&AVSDATA=XXN&SECURETOKEN=9eGKZsSldEU6mIdSEV5DB4wWd&PREFPSMSG=No%20Rules%20Triggered&SHIPTOCOUNTRY=US&AMT=14.75&SECURETOKENID=1850a8f2-f180-4474-aa31-35d736fd7921&TRANSTIME=2016-03-24%2007:58:48&HOSTCODE=A&COUNTRYTOSHIP=US&RESULT=0&BILLTOCOUNTRY=US&AUTHCODE=872PNI&EXPDATE=1218
I have tried removing the "?processor=PayflowGateway" to fix the multiple question mark issue in the URL, but that doesn't seem to help. I've also tried tagging the RETURNURL[xx] with xx being the length of the URL value, but that seems to be the same as not passing a RETURNURL at all as it just shows a confirmation page on paypal.com instead of redirecting back to my site.
In PayPal Manager, I set the "Show confirmation page" setting to "On my website", Return URL to blank, and Return URL Method to GET. Are there any other settings or API request changes I need to make to get this to return properly to my test site?
This problem is caused because you're URL-Encoding the RETURNURL parameter passed when requesting the secure token from payflowpro gateway.
See the Do Not URL Encode Name-Value Parameter Data section on the Integration Guide.
Also, here you can get some C# code working you can use.
And some guidelines about PayPal HTTP here.
Do not use System.Net.Http.HttpClient nor System.Net.WebClient to make the HTTP POST to request the secure token. Instead use the low level System.Net.WebRequest to be able to write the POST data unencoded.
For example:
private string RequestSecureToken(double amount)
{
var secureTokenId = Guid.NewGuid().ToString();
var requestId = Guid.NewGuid().ToString();
var pairs = new Dictionary<string, string>()
{
{"PARTNER", "PayPal"},
{"VENDOR", "VENDOR NAME"},
{"USER", "USER NAME"},
{"PWD", "PASSWORD"},
{"TRXTYPE", "S"},
{"AMT", amount.ToString()},
{"CREATESECURETOKEN", "Y"},
{"SECURETOKENID", secureTokenId},
{"SILENTTRAN", "TRUE"},
{"RETURNURL", "http://mycompany.com/success"},
{"ERRORURL", "http://mycompany.com/error"}
};
string postData = string.Join("&", pairs.Select(p => string.Format("{0}[{2}]={1}", p.Key, p.Value, p.Value.Length)));
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://pilot-payflowpro.paypal.com");
request.Method = "POST";
request.ContentType = "text/namevalue";
request.Headers.Add("X-VPS-CLIENT-TIMEOUT", "45");
request.Headers.Add("X-VPS-REQUEST-ID", requestId);
request.ContentLength = postData.Length;
using (var writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(postData);
}
//Get the response
var response = request.GetResponse();
using (var reader = new StreamReader(response.GetResponseStream()))
{
return reader.ReadToEnd();
}
}