Paypal checkout sdk call server

leo7706
Contributor
Contributor

Hello,

 

I need your help to implement paypal payment on my website. I am a beginner and maybe I don't understand something

 

Environment: ASP.net c#, MVC

 

As required, I created a PayPalClient class in a folder named "Model" (file PayPalClient.cs)

 

 

 

 

public class PayPalClient
{
/**
Set up PayPal environment with sandbox credentials.
In production, use LiveEnvironment.
*/
public static PayPalEnvironment environment()
{
return new SandboxEnvironment("ClientId","SecretClientId");
}

/**
Returns PayPalHttpClient instance to invoke PayPal APIs.
*/
public static HttpClient client()
{
return new PayPalHttpClient(environment());
}

public static HttpClient client(string refreshToken)
{
return new PayPalHttpClient(environment(), refreshToken);
}

/**
Use this method to serialize Object to a JSON string.
*/
public static String ObjectToJSONString(Object serializableObject)
{
MemoryStream memoryStream = new MemoryStream();
var writer = JsonReaderWriterFactory.CreateJsonWriter(
memoryStream, Encoding.UTF8, true, true, " ");
DataContractJsonSerializer ser = new DataContractJsonSerializer(serializableObject.GetType(), new DataContractJsonSerializerSettings { UseSimpleDictionaryFormat = true });
ser.WriteObject(writer, serializableObject);
memoryStream.Position = 0;
StreamReader sr = new StreamReader(memoryStream);
return sr.ReadToEnd();
}

 

 

 

 

Then I created a new class in the same folder name (file Paypal_CreateOrder.cs)

 

 

 

 

<removed>

 

 

And finally I added this code on my html page 

 

 

 

 

<script
		src="https://www.paypal.com/sdk/js?client-id=AZC3rUchW2sQM20buHp10EDFuuGHrezM9mwKWLDMHqps4tXUkKZcyq1UZcJrB7Ca-6UNAb7IGMFb9TlZ&currency=EUR"> 
</script>

<div id="paypal-button-container"></div>
<script>
	paypal.Buttons({
		createOrder: function (data, actions) {

            return fetch("", {
                method: 'post',
                headers: {
                    'content-type': 'application/json'
                }
			}).then(function (res) {
				return res.json();
			}).then(function (data) {
				return data.id;
			});
			//return actions.order.create({
			//	purchase_units: [{
			//		amount: {
			//			value: '0.01'
			//		}
			//	}]
			//});
				
		},
		onApprove: function (data, actions) {
			return actions.order.capture().then(function (details) {
				alert('Transaction completed by ' + details.payer.name.given_name);
				// Call your server to save the transaction
				return fetch('/Payment/ApproveOrder/' + data.orderID, {
					method: 'post',
					headers: {
						'content-type': 'application/json'
					},
					body: JSON.stringify({
						orderID: data.orderID
					})
				});
			});
		}
	}).render('#paypal-button-container');
</script>

 

 

 

 

As you can see, I don't know what to put in "fetch" for create order.. I tested to call a simple function in a controller with "/Test/TestFunction" where "Test" is the controller name and "TestFunction" is the function name into the controller. And this mechanic works. 

I tried to move the create order function into a controller but it not works, when I click on the button, the function is not called

 

 

 

 

public class PaypalController : Controller
    {
        //
        // GET: /Paypal/

        public ActionResult Index()
        {
            return View();
        }

        public async static System.Threading.Tasks.Task<PayPalHttp.HttpResponse> CreateOrder(bool debug = false)
        {
            var request = new OrdersCreateRequest();
            request.Prefer("return=representation");
            request.RequestBody(BuildRequestBody());
            //3. Call PayPal to set up a transaction
            var response = await PayPalClient.client().Execute(request);

            if (debug)
            {
                var result = response.Result<Order>();
                Console.WriteLine("Status: {0}", result.Status);
                Console.WriteLine("Order Id: {0}", result.Id);
                Console.WriteLine("Intent: {0}", result.CheckoutPaymentIntent);
                Console.WriteLine("Links:");
                foreach (LinkDescription link in result.Links)
                {
                    Console.WriteLine("\t{0}: {1}\tCall Type: {2}", link.Rel, link.Href, link.Method);
                }
                AmountWithBreakdown amount = result.PurchaseUnits[0].AmountWithBreakdown;
                Console.WriteLine("Total Amount: {0} {1}", amount.CurrencyCode, amount.Value);
            }

            return response;
        }
}

 

 

 

 

Can you help me and explain me how I can implement this?

Maybe I need to add a MapRoute in RouteConfig.cs file?

 

Thank you for your attention and your help

 

Login to Me Too
8 REPLIES 8

kpejr
Contributor
Contributor

I'm trying the same thing.  I can get it to call the controller try:

  return fetch("/paypal/createorder", {

After the action returns I just get a Uncaught SyntaxError: Unexpected token P in JSON at position 0  at  return res.json();

 

Login to Me Too

leo7706
Contributor
Contributor

Hello, 

 

thanks for your reply

 

I debugged the solution, and in HttpClient object, the Non-public menbers>AuthorizationInjector>Access Token and Refresh token is null.

Maybe the issue is here, How can I set a token or credential to make a correct script call?

 

 

 public static PayPalEnvironment environment()
        {
            return new SandboxEnvironment("clientID",
                "SecretClientId");
        }

        /**
            Returns PayPalHttpClient instance to invoke PayPal APIs.
         */
        public static HttpClient client()
        {
            HttpClient http = new PayPalHttpClient(environment());
                 //ACCESS TOKEN IS NULL IN HTTP OBJECT
            return http;// new PayPalHttpClient(environment());
        }

 

 

 

Login to Me Too

leo7706
Contributor
Contributor

Hello,

 

I solved two issue:

1- I changed the security protocol. It was Tls 1.0

I used this code on my Application_Start() method

 if (ServicePointManager.SecurityProtocol.HasFlag(SecurityProtocolType.Tls12) == false)
            {
                ServicePointManager.SecurityProtocol = ServicePointManager.SecurityProtocol | SecurityProtocolType.Tls12;
            }

and add this value on my app.config file 

<system.web>
    <trust level="High" /> 
</system.web>

 

Now the script no longer raises an error but nothing happens.

            return fetch("/Paypal/CreateOrder", {
                method: 'post',
                headers: {
                    'content-type': 'application/json'
                }
			}).then(function (res) {
				return res.json();
			}).then(function (data) {
				return data.orderID;
			});

 

fetch called my method that return a PayPalHttp.HttpResponse object. But the paypal login windows close and nothing happen. Maybe I missed something? Can you help me please?

Login to Me Too

leo7706
Contributor
Contributor

Hello,

 

After investigation, I still have the issue 

 

Unexpected token P in JSON at position 0  at  return res.json()

 

I followed the steps recommended by Paypal. My function returns a PalHttp.HttpResponse object. What is missing? httpResponse is not recognized as a valid Json?

Login to Me Too

leo7706
Contributor
Contributor

I think I found the source of my problem,

I call my CreateOrder method from my html page but since it didn't work, I removed the "static" from my method and I think that's what blocks everything. The javascript code does not wait for the response from create Order, hence the json error.
Do you know how to call a static async method in C # MVC? Do you have to go through a script? an aspx page?
Help me please

Login to Me Too

PayPal_Rachael
PayPal Employee
PayPal Employee

Hi @leo7706,

 

Thank you for posting here.

I recommend checking out our developer page https://developer.paypal.com/ . You should find help here and advice on how to resolve this issue. If you cannot find a solution you will also be able to open a ticket to our support team on that page. 

Rachael 

Login to Me Too

333333333333331
Contributor
Contributor

@leo7706Did you get this sorted in the end?

 

The examples in the documentation are pretty bad. No wonder why I've ended up where you were.

 

Using the `PayPalHttp.HttpResponse` is not returning any OrderId, just headers.

 

 

Login to Me Too

333333333333331
Contributor
Contributor

@leo7706Ok. That response needs to be converted to an order, then return that.

 

@PayPal_RachaelHello. Your .NET server / client code documentation is out of date which has cost me a bit of time, I'd expect more the amount you guys take per transaction tbh.

 

The server should return JSON Paypal order. `return Json(response.Result<PayPalCheckoutSdk.Orders.Order>());`

 

The client should be "Id" and not "OrderId".

 

createOrder: function () {
return fetch('/Paypal/CreatePayment'), {
method: 'post',
headers: {
'content-type': 'application/json'
}
}).then(function (res) {
return res.json();
}).then(function (data) {
return data.id; // Use the same key name for order ID on the client and server
});

Login to Me Too

Haven't Found your Answer?

It happens. Hit the "Login to Ask the community" button to create a question for the PayPal community.