Proper Way To See If Square Checkout Process Completed - c#

I am currently working on a C# Windows Form project that requires the user to pay prior to any processing taking place. I am using the Square .Net SDK for payment processing and have successfully managed to get a payment through to the sandbox environment using the Checkout URL generated by the Checkout API. My question is whether there is a simple way to get whether the payment process has been completed. Right now, I am just polling the API with the same order (with identical idempotency keys) and waiting for it to return an error that the order is no longer valid. Here is the backbone of my current code:
var bodyOrderLineItems = new List<CreateOrderRequestLineItem>();
long totalCost = 100;
var charge0 = new Money.Builder().Amount(totalCost).Currency("USD").Build();
bodyOrderLineItems.Add(new CreateOrderRequestLineItem.Builder("1").Name("Incredibly Valuable Product").BasePriceMoney(charge0).Build());
var order = new CreateOrderRequest.Builder()
.ReferenceId("reference_id")
.LineItems(bodyOrderLineItems)
.Build();
var body = new CreateCheckoutRequest.Builder("Test_iKey4", order)
.AskForShippingAddress(false)
.Build();
var checkoutApi = client.CheckoutApi;
try
{
CreateCheckoutResponse result = checkoutApi.CreateCheckout(locationsString, body);
System.Diagnostics.Process.Start(result.Checkout.CheckoutPageUrl);
while (true)
{
System.Threading.Thread.Sleep(5000);
//while payment hasn't gone through
try
{
result = checkoutApi.CreateCheckout(locationsString, body);
}
catch (ApiException e)
{
MessageBox.Show(e.Errors[0].Detail);
break;
}
}
MessageBox.Show("Payment Must Have Gone Through");
}
catch (ApiException e) { MessageBox.Show(e.Errors[0].Detail); };
Is this a valid approach? While this does seem to work, I feel like I am flooding the api with requests. I am pretty inexperienced with the Square API, so any help would be appreciated.

Typically the Checkout API is used within a website, as it includes a parameter redirect_url so that when the payment is complete, the user is redirected back to your side and it includes url parameters such as the transaction id. If you don't have a website, you can instead sign up for webhooks. The PAYMENT_UPDATED webhook will be sent out when a payment has been processed, so you do not need to do polling; just listen for the webhook.

Related

Caller doesn't connect into the conference

I'm trying to use Twilio to connect workers through a kind of Walkie Talkie (all the workers get a JWT to make browser calls using the Javascript SDK), for this I use the Twiml verb conference, when the worker press the conference button in the browser it sends a list of the active workers (except for the one who started the conference), I use the callSid as the name of the conference to make it unique and the CallResource to put every worker into the conference.
However, the workers in the list start listening the wait music for a conference room, but the caller automatically end the connection as soon as it is open, it doesn't even ends the conference, I don't know what's wrong with the code, I'm following the documentation for conferences in https://www.twilio.com/docs/voice/twiml/conference
Here is the method that's called when a conference needs to be created:
public VoiceResponse ConferenceTalk(List<string> recipients, string caller, string callSid)
{
TwilioClient.Init(my_account_sid, my_auth_token);
var confName = $"wt_{callSid}";
foreach (var recipient in recipients)
{
CallResource.Create(
url: new Uri($"{this.publicUrl}/Conference/WtConference/{confName}"),
to: new Twilio.Types.Client($"client:{recipient}"),
from: new Twilio.Types.Client(caller));
}
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference(confName,
startConferenceOnEnter: true,
endConferenceOnExit: true);
response.Append(dial);
return response;
}
Here is the endpoint the CallResource target with the url attribute:
[HttpPost]
public TwiMLResult WtConference()
{
var confName = Request.Url.Segments[Request.Url.Segments.Length - 1];
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference(confName);
response.Append(dial);
return TwiML(response);
}
I feel like the time all of this takes to happen might be causing your issues here. And the Twilio Voice SDK may not be the best product for this. I'd have to see maybe a video showing how the interaction works to fully commit to this.
In the meantime, I might try to speed up people joining the conference by sending the TwiML for the conference in the API call, not waiting for the webhook. e.g.:
public VoiceResponse ConferenceTalk(List<string> recipients, string caller, string callSid)
{
TwilioClient.Init(my_account_sid, my_auth_token);
var confName = $"wt_{callSid}";
var outboundResponse = new VoiceResponse();
var outboundDial = new Dial();
outboundDial.Conference(confName);
outboundResponse.Append(outboudDial);
foreach (var recipient in recipients)
{
CallResource.Create(
twiml outboundResponse,
to: new Twilio.Types.Client($"client:{recipient}"),
from: new Twilio.Types.Client(caller));
}
var response = new VoiceResponse();
var dial = new Dial();
dial.Conference(confName,
startConferenceOnEnter: true,
endConferenceOnExit: true);
response.Append(dial);
return response;
}
I say that Twilio Voice might not be best for this because on the Twilio back end, this is going through a whole stack that is built for making phone calls. Outbound calls are made at a rate of 1 call per second, so that might be slowing the calling of your list down.
You could consider the Twilio Video SDK for this instead (you can make audio only calls with the Twilio Video product). For this you would need to be able to trigger each of workers joining a room that was then used to distribute the audio. There aren't limits on calls per second, workers would just need to connect to a room and your application would be able to control who could talk at any one time.

Authentication in Dialogflow API V2 using C#

I have .NET Web API Project for the fulfillment API as our webhook in my Dialogflow agent. In our Post method of the controller, after getting the request from Dialogflow, I implement the explicit authentication as shown in the Google Cloud documentation for C#.
//jsonFileName is the name of the serviceAccountKey json generated from the Google Cloud Platform that's encrypted internally
public bool AuthExplicit(string projectId, string jsonFileName)
{
try
{
string JsonCredential = DecryptHelper.Decrypt(jsonFileName);
var credential = GoogleCredential.FromJson(JsonCredential).CreateScoped(LanguageServiceClient.DefaultScopes);
var channel = new Grpc.Core.Channel(
LanguageServiceClient.DefaultEndpoint.ToString(),
credential.ToChannelCredentials());
var client = LanguageServiceClient.Create(channel);
AnalyzeSentiment(client);
if (client != null)
{
return true;
}
else
{
return false;
}
}
internal void AnalyzeSentiment(LanguageServiceClient client)
{
var response = client.AnalyzeSentiment(new Document()
{
Content = "Authenticated.",
Type = Document.Types.Type.PlainText
});
var sentiment = response.DocumentSentiment;
string score = $"Score: {sentiment.Score}";
string magnitude = $"Magnitude: {sentiment.Magnitude}";
}
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything, and the projectId parameter is never used to authenticate. GCP docs are quite confusing, since when there is an AuthExplicit() that uses projectId, it uses it as a parameter for the buckets and only prints this on the console.
It works fine, until we test the service account key with a different agent. Expected output is that authentication would fail, but somehow it still passes.
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
The difference with the code is that after getting the client, when we call the AnalyzeSentiment() method, it doesn't do anything,
Does client.AnalyzeSentiment() return an empty response? Does the call hang forever?
It works fine, until we test the service account key with a different agent.
What is a different agent? A different User-Agent header?
Once the Post method goes through the AuthExplicit() method, it would only return a boolean. Is this the right way to authenticate? Or is there something else needed to invoke?
What does 'the Post method' refer to? What is the 'it' that would only return a boolean?

What Microsoft Azure service would be the best for me? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I am mainly a low level system developer so I am kind of lost with all those high level tools that Azure offers and all those buzz words.
So here's what I am trying to build: I am building a server that has a processing part (probably using Azure Batch) and a storage part (using storage, duh, and DBs). I would like to hide all of this behind an interface where client applications could:
Log in the users
Upload/Download selected files
Manage their currently running jobs or start some new ones
The client application might be on an iPad,Web browser, PC, ect... New features might arise or change on the server side. This is why would opt for a "server interface" to standardize all clients interactions, but i do not know what Azure tool would fit my needs for this interface. I am not looking for something low level as in building my own protocol and server, just something that would get the job done simply.
Cheers
Léon Cantin
Azure Mobile Services might be a good fit here. The upside is that you can prototype it quickly. In the current portal you can use Mobile Services with either a Node/JavaScript backend or an ASP.NET WebAPI backend. The node option is the fastest/easiest to implement. Some benefits of this approach:
The mobile service automatically gets created with a NoSQL-style table (thought it's actually stored in SQL Azure DB under the hood) and exposes REST endpoints for CRUD, along with customizable scripts in JS for each endpoint.
Mobile Services has native SDKs for Windows (C# or WinJS), iOS (Obj-C or Swift), Android (Java), and HTML5 (JavaScript) so you can easily connect any of your client apps to it.
The mobile service also supports background jobs written in JavaScript. This could be used for your background "processing part", though it's hard to evaluate without more details on what you want to do.
You also get built-in support for authentication (Twitter, FB, Google, MSA and AD) + push notifications (WNS, GCM, APNS, etc.)
In the new preview portal, mobile services are replaced by App Services (which includes mobile) but the node backend is not supported yet, hence my recommendation to use Mobile Services instead. You get more control with the ASP.NET WebAPI backend, but you also have to code more of the backend yourself. The advantage is that you can store your data anywhere (storage tables, DocumentDB, SQL DB, etc.)
For the file upload/download, you'd have to use Azure storage blobs, and if your mobile service needs to catalog the files associated to each user, you can simply save the full blob "path" for each file in the Mobile Service table.
The docs for Azure Mobile Services - along with many tutorials - are at http://azure.microsoft.com/en-us/documentation/services/mobile-services/. I also have 3 GitHub repos with sample code for Windows, iOS and Android that integrates with Mobile Services at https://github.com/search?q=user%3AActiveNick+AzureChatr, and a blog post that explains them at http://www.ageofmobility.com/2014/10/06/azurechatr-building-a-cross-platform-chat-app-for-windows-ios-android/.
I hope this helps.
Nick
I ended opting for a Web API which let me "call" functions from the server trough the HTTP protocole. the URL is the "name" of the function and the data are either serialized in body or in the URL. Really simple and flexible, it should work out of the box on any framework that can use HTTP or i might be able to find a library that lets me do it.
My Test code looks like this :
Client:
private async Task SubmitJob()
{
JobModel job = new JobModel { ID = 42, name = "HelloJob", completion = 100.0f };
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsJsonAsync<JobModel>("http://localhost:53122/Jobs/Submit", job);
if (response.IsSuccessStatusCode)
lblSuccess.Text = "Success!";
else
lblSuccess.Text = "Failure!";
}
catch (Exception ex)
{
string s = ex.ToString();
}
}
private async Task GetJobs()
{
try
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("http://localhost:53122/Jobs/Info");
if (response.IsSuccessStatusCode)
{
List<JobModel> jobList = await response.Content.ReadAsAsync<List<JobModel>>();
txtConsole.Text = "";
foreach(var job in jobList)
{
string line = "ID: " + job.ID + " Name: " + job.name + " completion: " + job.completion + "\r\n";
txtConsole.Text += line;
}
}
else
{
txtConsole.Text = "Failure!";
}
}
catch (Exception ex)
{
string s = ex.ToString();
}
}
Server:
public async Task<IHttpActionResult> GetJobInfo(int jobId)
{
try
{
JobModel a = new JobModel { name = "jobA", ID = 102, completion = 100.0f };
JobModel b = new JobModel { name = "jobB", ID = 104, completion = 42.0f };
JobModel c = new JobModel { name = "jobC", ID = 106, completion = 0.0f };
List<JobModel> result = new List<JobModel> { a, b, c };
return Ok(result);
}
catch (Exception ex)
{
return InternalServerError(ex);
}
}
[HttpPost]
public async Task<IHttpActionResult> SubmitJob([FromBody] JobModel submitedJob)
{
return Ok();
}

stripe.net - how to process subscriptionService.Get with no results

The stripe.com API only returns active subscriptions. I want to verify when I delete a subscription.
So this is going to return an error. I am not sure how to code for it.
I would prefer to make this call based on the subscriptionId. Will this cause an exception or will it return an error code?
Retrieving a subscription
var subscriptionService = new StripeSubscriptionService();
StripeSubscription stripeSubscription = subscriptionService.Get(*subscriptionId*);
Another options which is somewhat of a hack is to return all the subscriptions for the given customer and test to see if the subscriptionId was returned.
List all subscriptions for a customer
var subscriptionService = new StripeSubscriptionService();
IEnumerable<StripeSubscription> responses = subscriptionService .List(*customerId*);
foreach( var response in responses )
{
if (response.subscriptionId == subscriptionId)
{
// subscription exists and was not deleted
exit;
}
}
Per their documentation, https://stripe.com/docs/api they have 2 different APIs. You're trying to use the RESTful API, which is for retrieving information on demand.
They also have a WebHooks API, which requires you have an endpoint listening on your site which can accept event notifications. You configure these through your Dashboard with them.
The event type you're looking for specifically is probably the customer.subscription.deleted event, but there's a lot more you can do with them and I'd encourage you to explore all of those Webhooks.
I can't offer a code sample, as I don't use their service.
The strip.net example shows the subscriptionService.Cancel as a methed:
var subscriptionService = new StripeSubscriptionService();
subscriptionService.Cancel(*customerId*, *subscriptionId*);
But you can also use it as a function and it returns the subscription object.
var subscriptionService = new StripeSubscriptionService();
StripeSubscription stripeSubscription = subscriptionService.Cancel(*customerId*, *subscriptionId*);
If (stripeSubscription.Status != "canceled")
{
//subscription not cancelled
// take action
}
Per Stripe API docs:
Returns:
The canceled subscription object. Its subscription status will be set to "canceled" unless you've set at_period_end to true when canceling, in which case the status will remain "active" but the cancel_at_period_end attribute will change to true.One of the fiels is .status , witch is set to canceled.

401 when attempting to Tweet with Linq to Twitter

So I've looked at all the of the suggestions from the Linq to Twitter documentation regarding 401 statuses with Oauth and I honestly don't know what I'm doing wrong.
var auth = new PinAuthorizer
{
Credentials = new InMemoryCredentials
{
ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"],
ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"],
//OAuthToken = ConfigurationManager.AppSettings["twitterOAuthToken"], //don't include this
//AccessToken = ConfigurationManager.AppSettings["twitterAccessToken"] //or this for new users.
},
//
UseCompression = true,
GoToTwitterAuthorization = pageLink => Process.Start(pageLink),
GetPin = () =>
{
Console.WriteLine("/nAfter twitter authorizes your application you will be returned here or something/n");
Console.Write("Enter Pin here:");
return Console.ReadLine();
}
};
auth.Authorize();
using (var twitterCtx = new TwitterContext(auth, "https://api.twitter.com/1/",
"https://search.twitter.com/"))
{
try
{
twitterCtx.Log = Console.Out;
Console.WriteLine("Please provide tweet text");
string tweet = Console.ReadLine();
twitterCtx.UpdateStatus(tweet);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
I've ran this using the Pin Authentication method as well as the single user method (providing the oauth keys with config file). I'm able to query tweets but I can't update my status or send direct messages (I receive a 403 forbidden when I try to DM). I've provided a callback URL (albeit fake) so I can't think of why this isn't working. Any help would be appreciated.
PS this runs in Main, not sure if that matters
All you need is this overload of the TwitterContext ctor and it will use the proper base URLs:
new TwitterContext(auth)
The example you're using is for v1.0 URLs and LINQ to Twitter is on Twitter API v1.1 now. It will default to the proper base URLs.
If you're querying okay, but getting errors on update and DM, double check to make sure you aren't trying to tweet the same text. That's why I append a DateTime.Now to the end of test tweets - to guarantee uniqueness.

Categories

Resources