Skip to content

Instantly share code, notes, and snippets.

@jakejscott
Last active January 20, 2024 13:09
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save jakejscott/1b829ca1c9449e4788710867f346e90f to your computer and use it in GitHub Desktop.
Save jakejscott/1b829ca1c9449e4788710867f346e90f to your computer and use it in GitHub Desktop.
Paypal .net core C# sample
public class PayPalPaymentCreatedResponse
{
public string id { get; set; }
public string intent { get; set; }
public string state { get; set; }
public Payer payer { get; set; }
public Transaction[] transactions { get; set; }
public DateTime create_time { get; set; }
public Link[] links { get; set; }
public class Payer
{
public string payment_method { get; set; }
}
public class Transaction
{
public Amount amount { get; set; }
public object[] related_resources { get; set; }
}
public class Amount
{
public string total { get; set; }
public string currency { get; set; }
}
public class Link
{
public string href { get; set; }
public string rel { get; set; }
public string method { get; set; }
}
}
public class PayPalPaymentExecutedResponse
{
public string id { get; set; }
public string intent { get; set; }
public string state { get; set; }
public string cart { get; set; }
public Payer payer { get; set; }
public Transaction[] transactions { get; set; }
public DateTime create_time { get; set; }
public Link[] links { get; set; }
public class Payer
{
public string payment_method { get; set; }
public string status { get; set; }
public Payer_Info payer_info { get; set; }
}
public class Payer_Info
{
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string payer_id { get; set; }
public Shipping_Address shipping_address { get; set; }
public string country_code { get; set; }
public Billing_Address billing_address { get; set; }
}
public class Shipping_Address
{
public string recipient_name { get; set; }
public string line1 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
}
public class Billing_Address
{
public string line1 { get; set; }
public string line2 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
}
public class Transaction
{
public Amount amount { get; set; }
public Payee payee { get; set; }
public Item_List item_list { get; set; }
public Related_Resources[] related_resources { get; set; }
}
public class Amount
{
public string total { get; set; }
public string currency { get; set; }
public Details details { get; set; }
}
public class Details
{
public string subtotal { get; set; }
}
public class Payee
{
public string merchant_id { get; set; }
public string email { get; set; }
}
public class Item_List
{
public Shipping_Address1 shipping_address { get; set; }
}
public class Shipping_Address1
{
public string recipient_name { get; set; }
public string line1 { get; set; }
public string city { get; set; }
public string state { get; set; }
public string postal_code { get; set; }
public string country_code { get; set; }
}
public class Related_Resources
{
public Sale sale { get; set; }
}
public class Sale
{
public string id { get; set; }
public string state { get; set; }
public Amount amount { get; set; }
public string payment_mode { get; set; }
public string protection_eligibility { get; set; }
public string protection_eligibility_type { get; set; }
public Transaction_Fee transaction_fee { get; set; }
public string parent_payment { get; set; }
public DateTime create_time { get; set; }
public DateTime update_time { get; set; }
public Link[] links { get; set; }
}
public class Transaction_Fee
{
public string value { get; set; }
public string currency { get; set; }
}
public class Link
{
public string href { get; set; }
public string rel { get; set; }
public string method { get; set; }
}
}
// C# code to demostrate
// https://developer.paypal.com/docs/integration/web/accept-paypal-payment/
private static int RunPaypalDemo()
{
try
{
Task.Run(async () =>
{
HttpClient http = GetPaypalHttpClient();
// Step 1: Get an access token
PayPalAccessToken accessToken = await GetPayPalAccessTokenAsync(http);
Log.Information("Access Token \n{@accessToken}", accessToken);
// Step 2: Create the payment
PayPalPaymentCreatedResponse createdPayment = await CreatePaypalPaymentAsync(http, accessToken);
Log.Information("Created payment \n{@createdPayment}", createdPayment);
// Step 3: Get the approval_url and paste it into a browser
// It should look something like this: https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-97965369EL8295114
var approval_url = createdPayment.links.First(x => x.rel == "approval_url").href;
Log.Information("approval_url\n{approval_url}", approval_url);
//
// IMPORTANT: Stop the program here, and re-run only the section below (comment out Step 2 and Step 3) and paste in the correct paymentId and payerId
//
// Step 4: When paypal redirects to the return_url, we need to grab the PayerID and the paymentId and execute the payment
var paymentId = "PAY-9LN814307S704373KK6UFTHI";
var payerId = "LMWV7AASBDUQQ";
PayPalPaymentExecutedResponse executedPayment = await ExecutePaypalPaymentAsync(http, accessToken, paymentId, payerId);
Log.Information("Executed payment \n{@executedPayment}", executedPayment);
}).Wait();
}
catch (Exception ex)
{
Log.Error(ex, "Failed to login to PalPal");
return 1;
}
return 0;
}
private static HttpClient GetPaypalHttpClient()
{
const string sandbox = "https://api.sandbox.paypal.com";
var http = new HttpClient
{
BaseAddress = new Uri(sandbox),
Timeout = TimeSpan.FromSeconds(30),
};
return http;
}
private static async Task<PayPalAccessToken> GetPayPalAccessTokenAsync(HttpClient http)
{
var clientId = Config.Instance.PayPalClientId;
var secret = Config.Instance.PayPalSecret;
byte[] bytes = Encoding.GetEncoding("iso-8859-1").GetBytes($"{clientId}:{secret}");
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "/v1/oauth2/token");
request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(bytes));
var form = new Dictionary<string, string>
{
["grant_type"] = "client_credentials"
};
request.Content = new FormUrlEncodedContent(form);
HttpResponseMessage response = await http.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
PayPalAccessToken accessToken = JsonConvert.DeserializeObject<PayPalAccessToken>(content);
return accessToken;
}
private static async Task<PayPalPaymentCreatedResponse> CreatePaypalPaymentAsync(HttpClient http, PayPalAccessToken accessToken)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "v1/payments/payment");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.access_token);
var payment = JObject.FromObject(new
{
intent = "sale",
redirect_urls = new
{
return_url = "http://example.com/your_redirect_url.html",
cancel_url = "http://example.com/your_cancel_url.html"
},
payer = new { payment_method = "paypal" },
transactions = JArray.FromObject(new[]
{
new
{
amount = new
{
total = 7.47,
currency = "USD"
}
}
})
});
request.Content = new StringContent(JsonConvert.SerializeObject(payment), Encoding.UTF8, "application/json");
HttpResponseMessage response = await http.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
PayPalPaymentCreatedResponse paypalPaymentCreated = JsonConvert.DeserializeObject<PayPalPaymentCreatedResponse>(content);
return paypalPaymentCreated;
}
private static async Task<PayPalPaymentExecutedResponse> ExecutePaypalPaymentAsync(HttpClient http, PayPalAccessToken accessToken, string paymentId, string payerId)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, $"v1/payments/payment/{paymentId}/execute");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.access_token);
var payment = JObject.FromObject(new
{
payer_id = payerId
});
request.Content = new StringContent(JsonConvert.SerializeObject(payment), Encoding.UTF8, "application/json");
HttpResponseMessage response = await http.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
PayPalPaymentExecutedResponse executedPayment = JsonConvert.DeserializeObject<PayPalPaymentExecutedResponse>(content);
return executedPayment;
}
@bernatgy
Copy link

Thank you so much for this one... I have successfully "ported" all of the PayPal SDK's features which we needed, using parts of Program.cs.

@eriadel
Copy link

eriadel commented May 16, 2018

Great sample Jake! Is there any chance to figure out what's the PayPalAccessToken type ?
I can't see the definition in the code. Your help would be appreciated!

@vrait35
Copy link

vrait35 commented Oct 1, 2018

from where has PayPalAccessToken and other classes in Program.cs undertaken?

@muhammadbahrami
Copy link

Thank you ... ;*

@kevinah95
Copy link

class PayPalAccessToken
{
    public string scope { get; set; }
    public string access_token { get; set; }
    public string token_type { get; set; }
    public string app_id { get; set; }
    public int expires_in { get; set; }
    public string nonce { get; set; }
}

This is the PayPalAccessToken class.

@kite57
Copy link

kite57 commented Sep 26, 2021

Thank you for the wonderful explanation, do you have created any sample with creditcard and debitcard?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment