PayPal return page problem - c#

On payPal I added return page URL where user is redirected when payment is finished.
http://somewhere/back.aspx
But when I return from payPal after payment I don't get 'tx' or anything in queryString, what could be reason for that? I use correct token.

You cannot rely on the returnurl parameter for getting back any information about the PayPal transaction, those would be to easy to change.
You need to implement Instant Payment Notification (IPN) so you will get all the variables returned, here is an example : https://www.paypal.com/us/cgi-bin/webscr?cmd=p/pdn/ipn-codesamples-pop-outside

Related

How to get response from IPN cryptocurrencies

We're trying to receive payment with cryptocurrencies using coinpayment IPN. We are able to create a request and able to do a payment. However, not able to get success or failure response while user come back to the seller side.
Here is how payment request created:
public ActionResult IPN()
{
var uri = new UriBuilder("https://www.coinpayments.net/index.php");
uri.SetQueryParam("cmd", "_pay_auto");
uri.SetQueryParam("merchant", "merchant_key");
uri.SetQueryParam("allow_extra", "0");
uri.SetQueryParam("currency", "USD");
uri.SetQueryParam("reset", "1");
uri.SetQueryParam("success_url", "http://localhost:49725/home/SuccessResponse"); //todo: redirect to confirm success page
uri.SetQueryParam("key", "wc_order_5b7b84b91a882");
uri.SetQueryParam("cancel_url", "http://localhost:49725/home/FailiureResponse");
uri.SetQueryParam("order_id", "36");
uri.SetQueryParam("invoice", "PREFIX-36");
uri.SetQueryParam("ipn_url", "http://localhost:49725/?wc-api=WC_Gateway_Coinpayments");
uri.SetQueryParam("first_name", "John");
uri.SetQueryParam("last_name", "Smith");
uri.SetQueryParam("email", "a#a.com");
uri.SetQueryParam("want_shipping", "1");
uri.SetQueryParam("address1", "228 Park Ave S&address2");
uri.SetQueryParam("city", "New York");
uri.SetQueryParam("state", "NY");
uri.SetQueryParam("zip", "10003-1502");
uri.SetQueryParam("country", "US");
uri.SetQueryParam("item_name", "Order 33");
uri.SetQueryParam("quantity", "1");
uri.SetQueryParam("amountf", "100.00000000");
uri.SetQueryParam("shippingf", "0.00000000");
return Redirect(uri.ToString());
}
This will be redirected to the coinpayment site, once payment done, it is showing the following screen.
And trying to get data when user click on back to seller's site, I have tried to get data using Request.Form, but not getting any value in form.
The same thing, working with this woocommerce code, but I have no idea of PHP and how they are dealing with it.
Any thought to get IPN response?
Note: there is no development documentation or sample code available for IPN in .NET
Edit
I'm trying to get value from IPN success
Public ActionResult SuccessResponse()
{
var ipn_version = Request.Form["ipn_version"];
var ipn_id = Request.Form["ipn_id"];
var ipn_mode = Request.Form["ipn_mode"];
var merchant = Request.Form["merchant"];
var txn_id = Request.Form["txn_id"];
var status = Request.Form["status"];
return Content(status);
}
You cannot use localhost for a IPN callback. You must use a public domain name.
As an example I would change the following parameters:
var uri = new UriBuilder("https://www.coinpayments.net/api.php");
uri.SetQueryParam("success_url", "http://kugugshivom-001-site1.atempurl.com/Home/SuccessResponse");
uri.SetQueryParam("cancel_url", "http://kugugshivom-001-site1.atempurl.com/Home/FailiureResponse");
uri.SetQueryParam("ipn_url", "http://kugugshivom-001-site1.atempurl.com/Home/CoinPaymentsIPN"); // Public ActionResult CoinPaymentsIPN()
Since you are creating your own gateway you also need to implement it properly as described in the documentation at CoinPayments API and Instant Payment Notifications (IPN).
I have tested your success_url endpoint, and got status code: 100 (when entering status:100). I see you use form-data, but I don't know if that's on purpose / required.
Postman POST http://kugugshivom-001-site1.atempurl.com/Home/SuccessResponse
In Body tab form-data is selected with Bulk Edit values:
ipn_version:1.0
ipn_type:api
ipn_mode:hmac
ipn_id:your_ipn_id
merchant:your_merchant_id
txn_id:your_transaction_id
status:100
As updated answer stated by #Gillsoft AB, you should need to use valid IPN URL from the code end. Also webhook would not work with localhost. thus, you should listen the request with live server.
Simplest way to check webhook response is to use online tool such as Webhook Tester, it will provide an URL which you have to set as your IPN URL, whenever server will sends the data, you can simply see it to the web. To check that, create one URL and set as your IPN URL as below:
uri.SetQueryParam("ipn_url", "https://webhook.site/#/457f5c55-c9ce-4db4-8f57-20194c17d0ae");
After that run the payment cycle from local machine, payment server will sends notification to that IPN URL.
Make sure you understood it right! success_url and cancel_url are for user redirection, you will not get any response code over there, inspection of seller's store URL give your exact same URL that you have been passing though, so it is recommended to use unique URLs for each order(i.e add order id at last to the URL) which will give you an idea which order payment has been done or canceled.
http://localhost:49725/home/SuccessResponse?orderid=123
In order to test your local code, add following changes and deployed it to server.
1) Add one new method which will listen IPN response
[ValidateInput(false)]
public ActionResult IPNHandler()
{
byte[] param = Request.BinaryRead(Request.ContentLength);
string strRequest = Encoding.ASCII.GetString(param);
//TODO: print string request
//nothing should be rendered to visitor
return Content("");
}
2) Pass IPN URL while creating a request:
public ActionResult IPN()
{
var uri = new UriBuilder("https://www.coinpayments.net/index.php");
...
..
uri.SetQueryParam("success_url", "http://localhost:49725/home/SuccessResponse");
uri.SetQueryParam("cancel_url", "http://localhost:49725/home/FailiureResponse");
uri.SetQueryParam("ipn_url", "http://localhost:49725/home/IPNHandler");
....
..
return Redirect(uri.ToString());
}
You will get all status code responses in IPNHandler method.
Hope this helps!

Posting to a friends wall with exception

The exception I am getting is "The user hasn't authorized the application to perform this action". I know this is a well published exception but there are no rules which I can follow to get this code to work. I am trying to post to a friends wall via the API.
AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl }));
String accessToken = result.ExtraData["accesstoken"];
FacebookClient client = new FacebookClient(accessToken);
dynamic parameters = new ExpandoObject();
arameters.message = "Testing";
I have managed to get my friends facebook ids and this is facebookFriendID
object resTest = client.Post("/" + facebookFriendID + "/feed", parameters);
This is throwing the exception. Do I need to set any special options in my app to allow this to post to friends walls and/or do the users receving the post need to accept the app first? Is there any other params I need to send?
Thanks in advance
Posting to a friend's wall has been disabled
Post to friends wall via the API generate a high levels of negative user feedback, including “Hides” and “Mark as Spam" and so we are removing it from the API. If you want to allow people to post to their friend’s timeline from your app, you can invoke the feed dialog. Stories that include friends via user mentions tagging or action tagging will show up on the friend’s timeline (assuming the friend approves the tag).
https://developers.facebook.com/blog/post/2012/10/10/growing-quality-apps-with-open-graph/
ensure which authorization check the user has access to only his/her pages or whole application.
For basic authorization you can do like this
[BasicAuthorize]
public ActionResult Index()
{
// code will go here
}
For Anonymous
[AllowAnonymous]
public ActionResult Index()
{
// code will go here
}
[BasicAuthorize] requires at least user should login
[AllowAnonymous] Allow Every one to application
I think the exception is pretty explicit: your app must ask the target user for an authorization to post on its wall, and the user has to approve it. Imagine how would Facebook it be if any app could just post whatever it wanted on anyone's behalf in anyone's wall.
Depending on your implementation, you will need to ask for the publish_stream, status_update, or even other permission.
Do I pass this as a param? – CR41G14
I think it's more complicated than that, as you have to ask for the permission before acting. Check out this question for some information that may help you (here in SO there are several other questions about the topic, too).

User Master Account to send SMS on behalf of a Sub Account

I'm developing a feature for our product that will allow users to send SMS messages via Twilio and we handle all of the account issues. We have our Master Account and all of our customers will be sub accounts under us.
In an effort to not have to keep track of 1000+ auth tokens, we decided to use our Master Account credentials to send the SMS message however we still want it to roll up under the sub account. According to Twilio, this shouldn't be an issue.
My problem is that there is very little (that I've found) documentation for the c# library they provide. I'm not sure if what I've done is the correct way to accomplish what I described above and since I'm on a trial account until the project is finished and can be rolled out to production I have no way of testing.
var twilio = new TwilioRestClient("Master SID", "Master Auth Token");
var response = twilio.SendSmsMessage(sender, recipient.ConvertToE164Format(), message, null, "Subaccount SID");
The comment on this overload isn't really clear on if passing the subaccounts SID here will send the message as if I had logged into their account and sent it.
// applicationSid:
// Twilio will POST SmsSid as well as SmsStatus=sent or SmsStatus=failed to
// the URL in the SmsStatusCallback property of this Application. If the StatusCallback
// parameter above is also passed, the Application's SmsStatusCallback parameter
// will take precedence.
The callback url will be the same across all accounts so I don't need/care about that value.
Short Version:
If I log in with my Master Account details but pass the subaccount SID in the SendSmsMessage() method, which account does the message come from?
Twilio support finally got back to me and confirmed my fears that this wouldn't work. I do have to pull the subaccount information down and reinstantiate the twilioRestClient with the new credentials which I was hoping I could get away with not doing. Just a few extra lines.
var twilio = new TwilioRestClient("Master SID", "Master Auth Token");
var subAccount = twilio.GetAccount("SubAccount SID");
var subAccountClient = new TwilioRestClient(subAccount.Sid, subAccount.AuthToken);
var response = subAccountClient.SendSmsMessage(sender, recipient.ConvertToE164Format(), message);
return response.Sid;

Does FormsAuthentication.SetAuthCookie() Require a Redirect?

After checking a user's credentials and confirming they are good, I'm using FormsAuthentication.SetAuthCookie("Username", false); to authenticate the user.
In the masterpage I then use Page.User.Identity.IsAuthenticated to make sure we're dealing with a logged in user and not a guest.
The problem lies in first setting the auth cookie. When I set the auth cookie, immediately afterwards I run a method that uses Page.User.Identity.IsAuthenticated to change the welcome message from a generic "Welcome, guest!" message to a more personal "Welcome, username!" message. This does not work until I go to another page, so I know the login process has worked, but it seems I cannot access the information I need until a refresh or a redirect happens.
Do I need to redirect the user after setting the auth cookie in order use Page.User.Identity.IsAuthenticated to change the message?
I have seen this before so I know the answer is yes. (As in, yes you do need to redirect the user to correctly use Page.User.Identity.IsAuthenticated)
What I imagine is the cause is because IsAuthenticated evaluates the current request, and when the current request first came in it was recorded as not authenticated.
What you will need to do is apply whatever logic you have in said method without the check for IsAuthenicated (make it assume true).
Now I don't know the details of your method as to suggest how to re-factor it to cope with this, but you could split out the "Do Stuff" part into a separate function which you could then call directly from you login function to bypass the authentication check.
EDIT: To back up my assumption you can read this page.
The interesting part:
The forms-authentication ticket supplies forms-authentication
information to the next request made by the browser.
I'd like to point out that there's actually a way around this (since I've never seen this said in any other question like this). You can retrieve the cookie and its data where User.Identity's information comes from without a redirect. The thing is, the cookie just hasn't been sent to the browser yet.
It simply gets the cookie made by FormsAuthentication from the Response.Cookies object:
HttpCookie EncryptedCookie = Response.Cookies.Get(FormsAuthentication.FormsCookieName);
FormsAuthenticationTicket DecryptedCookie;
try {
DecryptedCookie = FormsAuthentication.Decrypt(EncryptedCookie.Value);
} catch (ArgumentException) {
// Not a valid cookie
return false;
}
// DecryptedCookie.Name: The Username
// DecryptedCookie.UserData: Any additional data, as a string. This isn't normally used
return !DecryptedCookie.Expired;

Paypal IPN Problem

I am developing a site where users can buy features using paypal. If user's paypal email is different from the email stored in our site how can i get notified about the user's payment via IPN?
You tagged your question with C#, so I'm assuming you're developing an ASP.NET site. And in the absence of more specific information, I'm going to assume you're using the default SqlMembershipProvider for your site.
So, to identify your user, you should probably use the ProviderUserKey property of the MembershipUser object. Use the following code to get the ProviderUserKey for your currently logged-in user:
MembershipUser currentUser = Membership.GetUser();
string userId = currentUser.ProviderUserKey.ToString();
Once you have a String containing the ProviderUserKey, you can pass it to PayPal using the custom HTML variable in your form:
<input type="hidden" name="custom" value="<%=userId%>"/>
When PayPal send the IPN message, it will send back the value that you set for the custom HTML variable. You can get the value from Response.Form and get the corresponding user:
object userId = Request.Form["custom"];
MembershipUser user = Membership.GetUser(userId);
Hope this helps!
You need to use the email of the user (the one which he/she used for your website) as an identifier.
When the user pays you, your website needs to send this email to Paypal as a "custom" field, and Paypal will send it back to you, among other IPN notification parameters.

Categories

Resources