I want to test PayPal Payment Advanced on my site an use this:https://ppmts.custhelp.com/app/answers/detail/a_id/929/. Now I finished intergrating it with my site. But now I can pay with PayPal Account, I failed to get payment with a Credit Card, I can't get any wrong response from PayPal when I use this API. This is my Code:
public NameValueCollection PayAdvanced(VM_BasketOrder basketOrder)
{
string baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority;
string ReturnURL = baseUrl + Url.Action("ReturnPayAdvanced", "ShoppingCart");
string CancelURL = baseUrl + Url.Action("CancelPay", "ShoppingCart");
StoredAddress billAddress = basketOrder.billto_sAddress;
StoredAddress shipAddress = basketOrder.shipto_sAddress;
NameValueCollection requestArray = new NameValueCollection()
{
{"PARTNER", "PayPal"},
{"VENDOR", "s04124226"},
{"USER", "g041234226"},
{"PWD", "k_123452346789"},
{"CREATESECURETOKEN", "Y"},
{"SECURETOKENID", genId()},
{"TRXTYPE", "S"},//A
{"SHIPAMOUNT", basketOrder.ShippingAmount.ToString()},
{"AMT", basketOrder.Total.ToString()},
{"TAX", basketOrder.SalesTax.ToString()},
// {"ACCT","4111111111111111"},
// {"EXPDATE","1215"},
{"CURRENCY", "USD"},
//{"SILENTTRAN","TRUE"},
{"RETURNURL", ReturnURL},
{"CANCELURL", CancelURL},
{"ERRORURL", CancelURL},
{"BILLTOFIRSTNAME",billAddress.Name.AddressNameSplit()[0]},
{"BILLTOLASTNAME", billAddress.Name.AddressNameSplit()[1]},
{"BILLTOSTREET", billAddress.Street1},
{"BILLTOCITY",billAddress.City},
{"BILLTOSTATE",billAddress.State},
{"BILLTOZIP",billAddress.Zip},
{"BILLTOCOUNTRY",billAddress.Country},
{"BILLTOPHONE","55555"},
{"SHIPTOFIRSTNAME", shipAddress.Name.AddressNameSplit()[0]},
{"SHIPTOLASTNAME", shipAddress.Name.AddressNameSplit()[1]},
{"SHIPTOSTREET", shipAddress.Street1},
{"SHIPTOCITY", shipAddress.City},
{"SHIPTOSTATE", shipAddress.State},
{"SHIPTOZIP",shipAddress.Zip},
{"SHIPTOCOUNTRY",shipAddress.Country},
{"SHIPTOPHONE","55555"},
};
NameValueCollection resp = run_payflow_call(requestArray);
return resp;
}
protected NameValueCollection run_payflow_call(NameValueCollection requestArray)
{
#region send request to Payflow
String nvpstring = "";
foreach (string key in requestArray)
{
//format: "PARAMETERNAME[lengthofvalue]=VALUE&". Never URL encode.
var val = requestArray[key];
nvpstring += key + "[ " + val.Length + "]=" + val + "&";
}
string urlEndpoint = "https://pilot-payflowpro.paypal.com/";
HttpWebRequest payReq = (HttpWebRequest)WebRequest.Create(urlEndpoint);
payReq.Method = "POST";
payReq.ContentLength = nvpstring.Length;
payReq.ContentType = "application/x-www-form-urlencoded";
StreamWriter sw = new StreamWriter(payReq.GetRequestStream());
sw.Write(nvpstring);
sw.Close();
#endregion
#region get Payflow response
HttpWebResponse payResp = (HttpWebResponse)payReq.GetResponse();
StreamReader sr = new StreamReader(payResp.GetResponseStream());
string response = sr.ReadToEnd();
sr.Close();
#endregion
#region parse string into array and return
NameValueCollection dict = new NameValueCollection();
foreach (string nvp in response.Split('&'))
{
string[] keys = nvp.Split('=');
dict.Add(keys[0], keys[1]);
}
return dict;
#endregion
}
protected string genId()
{
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var random = new Random();
var result = new string(
Enumerable.Repeat(chars, 16)
.Select(s => s[random.Next(s.Length)])
.ToArray());
return "MySecTokenID-" + result; //add a prefix to avoid confusion with the "SECURETOKEN"
}
I use this code, and I get passed a tokenid and token to next code.
<iframe src="#("https://payflowlink.paypal.com?MODE=TEST&SECURETOKENID="+ViewBag.SECURETOKENID+"&SECURETOKEN="+ViewBag.SECURETOKEN)" name="test_iframe" scrolling="no" style=" width:480px;height:490px;border:0px;"></iframe>
I get the PayPal iframe on my site, click the PayPal button, I can pay successfully, but when I enter a credit card number and click "pay now", I can't get money in my test account. Now I don't know how to debug my code, because it is executiin in PayPal, so I can't find where the mistake is in my code. So I pasted my code here, and hope some can help me.
today I find, when I use credit card pay, PNREF=V72A4DR7AE07, I can't get PPREF. when I use PayPal Account to pay, I can get PNREF and PPREF all. And PPREF is the PayPal transactionId.
Related
Received information today from PayPal:
IPN Verification Postback to HTTPS
If you are using PayPal’s Instant Payment Notification (IPN) service, you will >need to ensure that HTTPS is used when posting the message back to PayPal for >verification. After Sept 30, 2016 HTTP postbacks will no longer be supported.
I am using IPN and the live site is working but our DEV IPN listener which is using the sandbox at: https://www.sandbox.paypal.com/cgi-bin/webscr is broken.
I am confused about what I need to do to fix it. I added this code and the listener page loads without error again.
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
But when I try to test a transaction the listener never receives anything from PayPal. Is this because the server of the listener now has to be "https"?
Does PP sandbox now refuse to notify a non SSL address?
I got my c# code originally from a PayPal example but it is no longer on their site.
var useSandbox = Convert.ToBoolean(ConfigurationManager.AppSettings["UsePayPalSandboxYn"]);
var server = useSandbox ? "https://www.sandbox.paypal.com/cgi-bin/webscr" : "https://www.paypal.com/cgi-bin/webscr";
var req = (HttpWebRequest)WebRequest.Create(server);
// set values for the request back
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
//added today
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
| SecurityProtocolType.Tls11
| SecurityProtocolType.Tls12
| SecurityProtocolType.Ssl3;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
byte[] param = Request.BinaryRead(HttpContext.Current.Request.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
strRequest += "&cmd=_notify-validate";
req.ContentLength = strRequest.Length;
// send the request to PayPal and get the response
var streamOut = new StreamWriter(req.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
var streamIn = new StreamReader(req.GetResponse().GetResponseStream());
string strResponse = streamIn.ReadToEnd();
streamIn.Close();
switch (strResponse)
{
case "VERIFIED":
{
I do my debugging with a static IP address and a home router set up as a web server. It's going to be even harder if I have to set up ssl.
Can anyone point me in the right direction?
The only thing you need to do is make sure you're sending your verification POST back to PayPal to https:// instead of http://. You don't have to have an SSL installed on your site for your IPN listener to run on.
I just want to share my code that is working... hope that it can help you to make a little improvements on your code:
private void VerifyTask(HttpRequestBase ipnRequest, bool useLiveAccount = true)
{
string verificationResponse = string.Empty;
var request = (HttpWebRequest)WebRequest.Create(useLiveAccount
? WebConfigurationManager.AppSettings["PaypalURL"]
: WebConfigurationManager.AppSettings["SandboxURL"]);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
var param = ipnRequest.BinaryRead(ipnRequest.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
strRequest += "&cmd=_notify-validate";
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
using (var writer = new StreamWriter(request.GetRequestStream(), Encoding.ASCII))
{
writer.Write(strRequest);
writer.Close();
}
using (var reader = new StreamReader(request.GetResponse().GetResponseStream()))
{
verificationResponse = reader.ReadToEnd();
reader.Close();
}
if (verificationResponse.Equals("VERIFIED"))
{
//Make the validations here
}
}
Edit:
WebConfigurationManager.AppSettings["PaypalURL"] = "https://www.paypal.com/cgi-bin/webscr"
WebConfigurationManager.AppSettings["SandboxURL"] = "https://www.sandbox.paypal.com/cgi-bin/webscr"
I have facebook integrated on my login page, and now I'm trying to call a build-in action: books.rates using a Test App.
My app gets a valid access_token, and creates new feed items without problems. But when I'm tryng to make a books.rates API call, only works if the logged user is a real person (in my tests is me, also the App administrator), and fails allways with Error 400 when I try to rate a book with a Test User.
In both cases, the code is the same (only access_token and userid changes) and has "publish_actions" premission enabled. I think I'm missing something on Test App configuration, but I'm really lost right now.
Thanks!
Update 1
This is the code that makes the action. It's a test code so its very basic
Dictionary<string, string> postInfo = new Dictionary<string, string>();
postInfo["book"] = "http://www.whakoom.com/comics/6jMl7/52/4";
postInfo["rating:value"] = "4";
postInfo["rating:scale"] = "5";
postInfo["fb:explicitly_shared"] = "true";
string graphUrl = string.Format("https://graph.facebook.com/v2.1/{0}/books.rates?access_token={1}", FbUserID, FbAccessToken);
string fbResp = PostPageContent(graphUrl, postInfo);
private static string PostPageContent(string url, Dictionary<string,string> postData)
{
string postInfo = string.Empty;
foreach(string key in postData.Keys)
{
if (postInfo.Length > 0)
postInfo += "&";
postInfo += string.Format("{0}={1}", HttpContext.Current.Server.UrlEncode(key), HttpContext.Current.Server.UrlEncode(postData[key]));
}
var request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = postInfo.Length;
StreamWriter streamOut = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
streamOut.Write(postInfo);
streamOut.Close();
string retValue = string.Empty;
WebResponse response = request.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
retValue = reader.ReadToEnd();
reader.Close();
return retValue;
It seems that Test App with Test Users is unable to make books.rates calls until the main App is approved. The same api calls targeting a real App with a Test User works without problems.
As off right now i'm creating a post from my private account and on my
page. I'm trying to get the page it self to post the message i have
created. I been reading som documentation about page tokens. But
finding it difficult to find some eksampels. Does anyone of you guys
know the next step to getting to post messages as a page?? Would be
greatly thankful
public void CheckAutorization()
{
string app_Id = "my_app_id";
string app_secret = "my_secret_id";
string scope = "publish_stream, publish_actions";
if (Request["code"] == null)
{
Response.Redirect(string.Format(
"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}",
app_Id, Request.Url.AbsoluteUri, scope));
}
else
{
Dictionary<string, string> tokens = new Dictionary<string, string>();
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&scope={2}&code={3}&client_secret={4}",
app_Id, Request.Url.AbsoluteUri, scope, Request["code"].ToString(), app_secret);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string vals = reader.ReadToEnd();
foreach (string token in vals.Split('&'))
{
tokens.Add(token.Substring(0, token.IndexOf("=")),
token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
}
}
string access_token = tokens["access_token"];
var client = new FacebookClient(access_token);
var myAccount = client.Get("/me/accounts");
dynamic parameters = new ExpandoObject();
parameters.message = "test message";
parameters.link = "http://www.facebook.com";
parameters.picture = "http://www.fabric.co.uk/wp-content/uploads/2014/06/Facebook-teen-usage.jpg";
parameters.name = "facebook.fo";
parameters.caption = "test caption";
client.Post("/mypageUrl/feed", parameters);
}
}
What you need to post as a Page is a Page Access Token. Take a look at the Facebook docs about how to get it: https://developers.facebook.com/docs/facebook-login/access-tokens
Basically, you just call /me/accounts to get Access Tokens for all Pages and you use the particular Token to post instead of the User Token.
Here´s an article how to create an Extended Page Access Token without using the PHP SDK: http://www.devils-heaven.com/extended-page-access-tokens-curl/
I want to update the facebookpage using c# sdk. I have partially successful with this, the problem is whenever I post messages to the page, post is visible only for admin(i am the admin of the page)is logged In. I want the post or feed to be visible to every one who visit the page.
(even admin is logged out post's are not visible to admin also)
The following code i am trying to achieve
public ActionResult FacebookPagePost()
{
string app_id = "xxxx";
string app_secret = "xxx";
string scope = "publish_stream,manage_pages";
string page_Id = "xxX";
if (Request["code"] == null)
{
return Redirect(string.Format(
"https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri={1}&scope={2}",
app_id, Request.Url.AbsoluteUri, scope));
}
else
{
try
{
Dictionary<string, string> tokens = new Dictionary<string, string>();
string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&scope={2}&code={3}&client_secret={4}",
app_id, Request.Url.AbsoluteUri, scope, Request["code"].ToString(), app_secret);
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
StreamReader reader = new StreamReader(response.GetResponseStream());
string vals = reader.ReadToEnd();
foreach (string token in vals.Split('&'))
{
tokens.Add(token.Substring(0, token.IndexOf("=")),
token.Substring(token.IndexOf("=") + 1, token.Length - token.IndexOf("=") - 1));
}
}
string access_token = tokens["access_token"];
var client = new FacebookClient(access_token);
dynamic fbAccounts = client.Get("/me/accounts");
dynamic messagePost = new ExpandoObject();
messagePost.picture = "http://pic.com/pic.png";
messagePost.link = "http://www.examplearticle.com";
messagePost.name = "name goes here";
messagePost.description = "description goes here";
//Loop over the accounts looking for the ID that matches your destination ID (Fan Page ID)
foreach (dynamic account in fbAccounts.data) {
if (account.id == page_Id)
{
//When you find it, grab the associated access token and put it in the Dictionary to pass in the FB Post, then break out.
messagePost.access_token = account.access_token;
break;
}
}
client.Post("/" + page_Id + "/feed", messagePost);
}
catch (FacebookOAuthException ex)
{
}
catch (Exception e)
{
}
}
}
1) Create a Facebook App at: developers.facebook.com and get yourself an APPID and APPSECRET. (there are a lot of tutorials online for doing this so I will skip repeating it)
2) Go to: http://developers.facebook.com/tools/explorer and choose your app from the dropdown and click "generate access token".
3) After that do the following steps here:
https://stackoverflow.com/questions/17197970/facebook-permanent-page-access-token to get yourself a permanent page token.
(I can not stress this enough, follow the steps carefully and thoroughly)*
*I have tool I built that does this for me, all I enter is the APPID, APPSECRET and ACCESSTOKEN which the tool then generates a permanent page token for me. Anyone is welcomed to use it and help make it better,
https://github.com/devfunkd/facebookpagetokengenerator
=========================================================================
Ok at this point you should have your APPID, APPSECRET and a PERMANENT PAGE TOKEN.
=========================================================================
In your Visual Studio solution:
4) Using Nuget:Install-Package Facebook
5) Implement the Facebook client:
public void PostMessage(string message)
{
try
{
var fb = new FacebookClient
{
AppId = ConfigurationManager.AppSettings.Get("FacebookAppID"),
AppSecret = ConfigurationManager.AppSettings.Get("FacebookAppSecret"),
AccessToken = ConfigurationManager.AppSettings.Get("FacebookAccessToken")
};
dynamic result = fb.Post("me/feed", new
{
message = message
});
}
catch (Exception exception)
{
// Handle your exception
}
}
I hope this helps anyone who is struggling to figure this out.
PayPal NVP Partial refunds refunding full amount though specified the RefundType as "Partial"
Here is the request i am using
public string Refund_Partial(string transactionID, string refundType,string Amount)
{
string strCredentials = "USER=" + strUsername + "&PWD=" + strPassword + "&SIGNATURE=" + strSignature;
string strNVP = strCredentials;
strNVP += "&METHOD=RefundTransaction&VERSION=" + strAPIVersion;
strNVP += "&TRANSACTIONID=" + transactionID + "&REFUNDTYPE=" + refundType + "¤cy=USD" + "&AMOUNT=" + Amount;
//Create web request and web response objects, make sure you using the correct server (sandbox/live)
HttpWebRequest wrWebRequest = (HttpWebRequest)WebRequest.Create(strNVPSandboxServer);
//Set WebRequest Properties
wrWebRequest.Method = "POST";
// write the form values into the request message
StreamWriter requestWriter = new StreamWriter(wrWebRequest.GetRequestStream());
requestWriter.Write(strNVP);
requestWriter.Close();
// Get the response.
HttpWebResponse hwrWebResponse = (HttpWebResponse)wrWebRequest.GetResponse();
StreamReader responseReader = new StreamReader(wrWebRequest.GetResponse().GetResponseStream());
// and read the response
string responseData = responseReader.ReadToEnd();
responseReader.Close();
return responseData;
}
Can anyone please let me know do i need to include more parameters to do a partial refund?
Can you change the Parameters value for currencyCode and Amount, From
"¤cy=USD" + "&AMOUNT=" + Amount
to
"CURRENCYCODE=USD" + "&AMT=" + Amount
Have a look at RefundTransaction API Operation (NVP).
May be PayPal is looking for AMT parameter which is not there, which is why it is refunding in Full