Skip to content

Instantly share code, notes, and snippets.

Last active April 7, 2023 17:55
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
The solution to getting Paypal's verify endpoint to work was to serialize JSON manually like so:
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace server.Payment
public class PaymentController : Controller
private static readonly HttpClient client = new HttpClient();
public async Task<IActionResult> HandleWebhook()
var json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
var headers = HttpContext.Request.Headers;
await VerifyEvent(json, headers);
// handle etc...
return Ok();
private async Task VerifyEvent(string json, IHeaderDictionary headerDictionary)
var bearerToken = await Authenticate();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", bearerToken);
// Without this direct JSON serialization, PayPal WILL ALWAYS return verification_status = "FAILURE".
// This is probably because the order of the fields are different and PayPal does not sort them.
var paypalVerifyRequestJsonString = $@"{{
""transmission_id"": ""{headerDictionary["PAYPAL-TRANSMISSION-ID"][0]}"",
""transmission_time"": ""{headerDictionary["PAYPAL-TRANSMISSION-TIME"][0]}"",
""cert_url"": ""{headerDictionary["PAYPAL-CERT-URL"][0]}"",
""auth_algo"": ""{headerDictionary["PAYPAL-AUTH-ALGO"][0]}"",
""transmission_sig"": ""{headerDictionary["PAYPAL-TRANSMISSION-SIG"][0]}"",
""webhook_id"": ""<get from paypal developer dashboard>"",
""webhook_event"": {json}
var content = new StringContent(paypalVerifyRequestJsonString, Encoding.UTF8, "application/json");
var resultResponse = await client.PostAsync("", content);
var responseBody = await resultResponse.Content.ReadAsStringAsync();
var verifyWebhookResponse = JsonConvert.DeserializeObject<VerifyWebhookResponse>(responseBody);
if (verifyWebhookResponse.verification_status != "SUCCESS")
throw new Exception("failed to verify webhook response");
private async Task<string> Authenticate()
// TODO: make all hard coded values configurable
var request = WebRequest.Create("");
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.Headers.Add("grant_type", "client_credentials");
var postData = "grant_type=client_credentials";
var byteArray = Encoding.UTF8.GetBytes(postData);
var dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
var clientId = "<get from paypal developer dashboard>";
var clientSecret = "<get from paypal developer dashboard>";
var encoded = Convert.ToBase64String(Encoding.GetEncoding("ISO-8859-1")
.GetBytes(clientId + ":" + clientSecret));
request.Headers.Add("Authorization", "Basic " + encoded);
var response = await request.GetResponseAsync();
using (dataStream = response.GetResponseStream())
var reader = new StreamReader(dataStream);
var responseFromServer = reader.ReadToEnd();
var token = JsonConvert.DeserializeObject<TokenResponse>(responseFromServer);
return token.access_token;
catch (WebException e)
string content;
using (var reader = new StreamReader(e.Response.GetResponseStream()))
content = reader.ReadToEnd();
Console.WriteLine("content", content);
Copy link

itfm commented Jul 21, 2022

What does VerifyWebhookResponse look like or where can I find a sample response from PayPal?

Copy link

HenryBJ commented Aug 4, 2022

@itfm It must look like this:

  "verification_status": "SUCCESS"

Copy link

HenryBJ commented Aug 4, 2022

@jsdevtom Thanks for your help bro !!!

Copy link

jsdevtom commented Aug 8, 2022

@HenryBJ You're very welcome

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