Paypal .Net SDK payment API calls on behalf of third party Permission - c#

I use Paypal .Net SDK (https://github.com/paypal/PayPal-NET-SDK ) for payment API calls. It needs an APIContext object to be passed in API calls.
By using clientid and clientsecret of my paypal app, I can obtain accesstoken to create the APIContext object. But this makes payment into my merchant account.
I wanted to make payment and refund API calls on behalf of other merchants. For that I used Paypal Permission SDK (https://github.com/paypal/permissions-sdk-dotnet) to obatain permissions from Third Party Merchants. Once a merchant grants permission, I get token and secret. At this stage I cannot find any documentation how do I use that token and secret to call paypal API?
Can anyone guide me how to use that token and secret (received from permission API) to make valid APIContext, which can be used to call various paypal.net sdk API calls?

My answer is a bit late, but may help others as I found this question when searching for how to do this.
This applies if using the PayPal .NET SDK.
Create a PayPal.Api.Payee object and add this to your PayPal.Api.Transaction object that you use to make your payment.
Example 1:
var payee = new PayPal.Api.Payee()
{
email = "test#example.com"
}
var transaction = new PayPal.Api.Transaction();
transaction.payee = payee;
Example 2:
var paypal = new PayPal.Api.Transaction()
{
description = "Transaction description.",
invoice_number = "123",
amount = new Amount()
{
currency = "USD",
total = "100.00",
details = new Details()
{
tax = "0",
shipping = "25.00",
subtotal = "75.00"
}
},
item_list = new ItemList()
{
items = new List<Item>()
{
new Item()
{
name = "title",
currency = "USD",
price = "75.00",
quantity = "1",
sku = "MySKU"
}
}
},
payee = new Payee()
{
email = "email#example.com"
}
};
Instead of email you could use merchant_id or phone to identify the third party to receive the funds.
Note: the third party must have granted your PayPal application the appropriate permission for the type of transaction you are attempting.

Related

Stripe first Subscription payment missing meta data

I am using stripe API and .net to create subscriptions.
my issue is that when i create a subscription the meta data is saved on the subscription instead of being saved on the payment.
is there a way to save the meta data on the first subscription payment instead?
that is what i have tried so far :
var subscriptionOptions = new SubscriptionCreateOptions
{
Customer = customerID,
Items = new List<SubscriptionItemOptions>
{
new SubscriptionItemOptions
{
Price = priceID,
Quantity = 1
},
},
PaymentBehavior = "default_incomplete",
Metadata = new Dictionary<string, string>
{
{ "id", "123"},
{ "name", "david" },
},
};
subscriptionOptions.AddExpand("latest_invoice.payment_intent");
var subscriptionService = new SubscriptionService();
try
{
Subscription subscription = await subscriptionService.CreateAsync(subscriptionOptions);
return new SubscriptionCreateResponse
{
SubscriptionId = subscription.Id,
ClientSecret = subscription.LatestInvoice.PaymentIntent.ClientSecret,
};
}
No, the subscription metadata is not propagated to the generated invoices or the payment intents used within those invoices. If you want metadata on either of those, you'll need to set up a process to update that using your own code.
You could, for example, set this up using webhooks. You could listen for invoice.paid webhooks and then retrieve the subscription to get the metadata and update the Payment Intent related to that invoice.

Updating User's sign in Email Address via Microsoft Graph API in C#

Using the Microsoft Graph API in C# I can successfully get a user's details and update say their first name, or details held in extension attributes. However, is it possible to update the email address that they use to sign in with?
I can see this held in the Identities section, but I can't see a way of updating the values held there.
is it possible to update the email address that they use to sign in
with?
if you refer to User.identities property which:
Represents the identities that can be used to sign in to this user
account.
then yes it is supported to update this property.
Note: Updating the identities property requires the
User.ManageIdentities.All permission
PATCH https://graph.microsoft.com/v1.0/users/{id-or-upn}
{
"identities": [
{
"signInType": "emailAddress",
"issuer": "{tenant-name}",
"issuerAssignedId": "{user-signIn-email}"
}
]
}
C# example
var tenant = "contoso.onmicrosoft.com";
var existingEmailAddress = "current_email#contoso.com";
var newEmailAddress = "new_email#contoso.com";
//1 . find user
var users = await graphClient.Users
.Request()
.Filter($"identities/any(c:c/issuerAssignedId eq '{existingEmailAddress}' and c/issuer eq '{tenant}')")
.Select("displayName,id,userPrincipalName")
.GetAsync();
var foundUser = users.FirstOrDefault();
//2. update user identity
var user = new User
{
Identities = new List<ObjectIdentity>()
{
new ObjectIdentity
{
SignInType = "emailAddress",
Issuer = tenant,
IssuerAssignedId = newEmailAddress
}
}
};
await graphClient.Users[foundUser.Id].Request().UpdateAsync(user);
userPrincipalName is the field that you need to update. As per Update User Docs Using body below works for me.
PATCH https://graph.microsoft.com/v1.0/users/{USER-ID}
{
"userPrincipalName": "alias#domain.com"
}
Add this field to the C# call and should work.

Create and Validate Invitation Code / Token

Using ASP.NET Core I am creating a system to invite users to Join a Group, Get Free Credits, ...
When inviting a User to Join a Group I create an Invitation which is saved in the database:
The token is saved on the database along with other information:
Invitation invitation = new Invitation {
InvitationType = "JoinGroup",
Completed = false,
Expiry = DateTime.Now.AddDays(4),
Token = some_token,
Parameters = new List<Parameter> {
new Parameter { Name = "GroupId", Value = 22 },
new Parameter { Name = "RoleId", Value = "Admin" },
new Parameter { Name = "Email", Value = "someuser#name.com" },
}
}
Then I send an email with an url:
/invite?token=some_token
When the user accesses the url I get the record with the given token.
With that information I do whatever I need to do, for example, add User to the Group.
Question
How should I create a unique token?
Which information should I include in the token?
And how should I validate it?
ASP.NET Core Identity provides functionality for generating tokens for different purposes.
Using the UserManager you can generate tokens for multiple purposes.
One of the methods available is the UserManager.GenerateUserTokenAsync(TUser, String, String).
You can verify the token using the UserManager.VerifyUserTokenAsync(TUser, String, String, String) method.
Reference To Documentation
Here is link that will help you getting started:
Identity Tokens

Unable to authenticate Google Calendar API v3 programmatically?

Perhaps I am the only one that thinks Google's API documentation is awful but I've spent more time on this simple task than I wanted.
Currently my project is using a GDATA implementation to connect with the Google Calendar API v2. I followed this guide: http://www.codeproject.com/Articles/565032/Google-Calendar-Integration-in-ASP-NET-Create-ed
But I noticed that Google is deprecating version 2 of their API this fall. I am trying to figure out how I can connect to their version 3 API which appears to be using OAuth2.
After reading their documentation and searching the internet >:( - The problem I keep running into is EVERY sample, tutorial or youtube video I've come across that shows how to implement this involve the Google consent screen where the user clicks "Accept".
I've tried doing the following but honestly not sure if it's even the right direction?
// Register the authenticator. The Client ID and secret have to be copied from the API Access
// tab on the Google APIs Console.
var provider = new NativeApplicationClient(GoogleAuthenticationServer.Description);
provider.ClientIdentifier = "MY_CLIENT_ID";
provider.ClientSecret = "MY_CLIENT_SECRET";
// Create the service. This will automatically call the previously registered authenticator.
var service = new CalendarService();
My application doesn't need the user's account/consent (OAuth), I need to connect like I am currently in my code-behind.
So the question is how do I "upgrade" my current implementation to v3? Do I use OAuth, Service Account? I've found plenty of examples showing the v3 usages for how to retrieve events and insert them... but they all authenticate with a user consent screen on the front end.
Here is my current GData implementation...
public class GoogleGateway : IGoogleGateway
{
private readonly IRepository<UserSetting> _settingsRepository;
private Service _googleService;
private CalendarService _googleCalendar;
private Uri _calendarUri;
public GoogleGateway(IRepository<UserSetting> settingsRepository)
{
_settingsRepository = settingsRepository;
}
public IEnumerable<EventEntry> GetAllEvents(DateTime? startDate)
{
if (!Connect()) return new List<EventEntry>();
// Create the query object:
EventQuery query = new EventQuery();
query.Uri = _calendarUri;
if (startDate != null)
query.StartTime = startDate.Value;
// Tell the service to query:
EventFeed calFeed = _googleCalendar.Query(query);
return calFeed.Entries.Cast<EventEntry>();
}
public bool Connect()
{
var calSettings = _settingsRepository.Get().Where(x => x.Setting == "Calendar");
if (calSettings.Any())
{
var username = calSettings.First(x => x.Meta == "GoogleUsername").Value;
var password = calSettings.First(x => x.Meta == "GooglePassword").Value;
var calendarUri = new Uri(calSettings.First(x => x.Meta == "CalendarFeed").Value);
var applicationName = calSettings.First(x => x.Meta == "ApplicationName").Value;
_calendarUri = calendarUri;
//FeedQuery feedQuery = new FeedQuery();
_googleService = new Service("cl", applicationName);
_googleCalendar = new CalendarService(applicationName);
// Set your credentials:
_googleService.setUserCredentials(username, password);
_googleCalendar.setUserCredentials(username, password);
return true;
}
return false;
}
public void AddEvent(string title, string contents, string location, DateTime startTime, DateTime endTime)
{
if (!Connect()) return;
EventEntry.EVENT_CATEGORY = new AtomCategory("Appointments");
EventEntry entry = new EventEntry
{
Title = { Text = title },
Content = { Content = contents },
};
// Set the title and content of the entry.
// Set a location for the event.
Where eventLocation = new Where();
eventLocation.ValueString = location;
entry.Locations.Add(eventLocation);
When eventTime = new When(startTime, endTime);
entry.Times.Add(eventTime);
Uri postUri = new Uri("http://www.google.com/calendar/feeds/default/private/full");
// Send the request and receive the response:
AtomEntry insertedEntry = _googleCalendar.Insert(postUri, entry);
}
public void DeleteEvent(string eventId)
{
if (!Connect()) return;
var events = GetAllEvents(null);
var appointment = events.First(x => x.EventId == eventId);
_googleService.Delete(appointment);
}
}
I'm growing desperate at this point, any help would be very appreciated. Include your twitter handle in your answer and I'll buy you a coffee!
UPDATED
I currently have the following, but I is still not authenticating... :(
static CalendarService BuildService()
{
String serviceAccountEmail = "xxxxxxxxxxxxx-31xxxxxxxxxxxxxxxxxxx#developer.gserviceaccount.com";
var certPath = HttpContext.Current.Server.MapPath("/xxxxxxxxxxxx.p12");
var certificate = new X509Certificate2(certPath, "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { CalendarService.Scope.Calendar }
}.FromCertificate(certificate));
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential, <<<<<< DOES NOT RESOLVE!
ApplicationName = "MyApplication",
});
var test = service.Calendars.Get("xxxxxxxxxxxxxxxxxx#group.calendar.google.com");
return service;
}
The problem is that you are storing credentials in plaintext. In Oauth2 the users won't give you their credentials (thus access to everything) but instead they enable your app to access the data of a specific type / scope.
It's not clear from your description whether you only ever access one calendar fully in your control or you have multiple users. In the first case the answer would be use service account (https://developers.google.com/accounts/docs/OAuth2ServiceAccount). In the second case if you are a calendar app with many users, you will need to go down the user consent road and you should read on :)
For offline access you can specify that the access_type should be offline when retrieving the credentials for the first time. Together with the access token you'll also get a refresh token, which you can use to re-authenticate at any later time without any more user clicks (https://developers.google.com/accounts/docs/OAuth2WebServer#refresh). However, at least one consent screen it is.

How to create user in salesforce using Web/REST API from c#?

I am working on a WCF service where I need to sync the users from Windows Active Directory to a Salesforce account. I don't want to use any 3rd party tool or service, but want to develop a new one. I tried to use Partner WSDL provided by salesforce, but couldn't get how I can utilize it to create a new user in salesforce. Please give me some pointer on how I can utilize Web/REST API to create a new user in salesforce. Any sample code or link which can explain it.
For Salesforce's REST API you can use SalesforceSharp.
The sample code below will create an user on your Salesforce account:
var client = new SalesforceClient();
var authenticationFlow = new UsernamePasswordAuthenticationFlow
(clientId, clientSecret, username, password);
client.Authenticate (authenticationFlow);
var user = new
{
Username = "email#domain.com",
Alias = "userAlias",
// The ID of the user profile (Standard User, System Administrator, etc).
ProfileId = "00ei000000143vq",
Email = "email#domain.com",
EmailEncodingKey = "ISO-8859-1",
LastName = "lastname",
LanguageLocaleKey = "pt_BR",
LocaleSidKey = "pt_BR",
TimeZoneSidKey = "America/Sao_Paulo"
};
var id = client.Create ("User", user);

Categories