简体   繁体   中英

how to integrate asp.net mvc 5 with latest Paypal checkout .net sdk v2?

I tried to use Paypal Checkout SDK V2 in my Asp.Net MVC 5 project with .Net Framework 4.7.2 the but this seems to be something missing or wrong from my side.

I am just trying to integrate Paypal Checkout sdk and want to create an order so that my payment 'll be proceed by some paypal user and I only want to show one Pay Now button.

The SDK link is here:

https://github.com/paypal/Checkout-NET-SDK

and followed these links

https://developer.paypal.com/docs/checkout/reference/server-integration/get-transaction/#on-the-client https://developer.paypal.com/demo/checkout/#/pattern/server

This is my code for trying it

C# Code


public class CheckoutController : Controller
{
   
    public ActionResult Index()
    {
        ViewBag.ClientId = PayPalClient.ClientId;
        ViewBag.CurrencyCode = "GBP"; // Get from a data store
        ViewBag.CurrencySign = "£";   // Get from a data store

        return View();
    }
    //[Route("api/paypal/checkout/order/create")]
    public async static Task<HttpResponse> createOrder()
    {
        HttpResponse response;
        // Construct a request object and set desired parameters
        // Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
        var order = new OrderRequest()
        {
            CheckoutPaymentIntent = "CAPTURE",
            PurchaseUnits = new List<PurchaseUnitRequest>()
                {
                    new PurchaseUnitRequest()
                    {
                        AmountWithBreakdown = new AmountWithBreakdown()
                        {
                            CurrencyCode = "USD",
                            Value = "100.00"
                        }
                    }
                },
            ApplicationContext = new ApplicationContext()
            {
                ReturnUrl = "https://www.example.com",
                CancelUrl = "https://www.example.com"
            }
        };


        // Call API with your client and get a response for your call
        var request = new OrdersCreateRequest();
        request.Prefer("return=representation");
        request.RequestBody(order);
        response = await PayPalClient.Client().Execute(request);
        var statusCode = response.StatusCode;
        Order 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);
        }
        return response;
    }

    public async static Task<HttpResponse> captureOrder()
    {
        // Construct a request object and set desired parameters
        // Replace ORDER-ID with the approved order id from create order
        var request = new OrdersCaptureRequest("APPROVED-ORDER-ID");
        request.RequestBody(new OrderActionRequest());
        HttpResponse response = await PayPalClient.Client().Execute(request);
        var statusCode = response.StatusCode;
        Order result = response.Result<Order>();
        Console.WriteLine("Status: {0}", result.Status);
        Console.WriteLine("Capture Id: {0}", result.Id);
        return response;
    }

    /// <summary>
    /// This action is called when the user clicks on the PayPal button.
    /// </summary>
    /// <returns></returns>
    //[Route("api/paypal/checkout/order/create")]
    public async Task<SmartButtonHttpResponse> Create()
    {
        var request = new PayPalCheckoutSdk.Orders.OrdersCreateRequest();

        request.Prefer("return=representation");
        request.RequestBody(OrderBuilder.Build());

        // Call PayPal to set up a transaction
        var response = await PayPalClient.Client().Execute(request);

        // Create a response, with an order id.
        var result = response.Result<PayPalCheckoutSdk.Orders.Order>();
        var payPalHttpResponse = new SmartButtonHttpResponse(response)
        {
            orderID = result.Id
        };
        return payPalHttpResponse;
    }


    /// <summary>
    /// This action is called once the PayPal transaction is approved
    /// </summary>
    /// <param name="orderId"></param>
    /// <returns></returns>
    //[Route("api/paypal/checkout/order/approved/{orderId}")]
    public ActionResult Approved(string orderId)
    {
        return Json("Sucess", JsonRequestBehavior.AllowGet);
    }

    /// <summary>
    /// This action is called once the PayPal transaction is complete
    /// </summary>
    /// <param name="orderId"></param>
    /// <returns></returns>
    //[Route("api/paypal/checkout/order/complete/{orderId}")]
    public ActionResult Complete(string orderId)
    {
        // 1. Update the database.
        // 2. Complete the order process. Create and send invoices etc.
        // 3. Complete the shipping process.
        return Json("Completed", JsonRequestBehavior.AllowGet);
    }

    /// <summary>
    /// This action is called once the PayPal transaction is complete
    /// </summary>
    /// <param name="orderId"></param>
    /// <returns></returns>
    //[Route("api/paypal/checkout/order/cancel/{orderId}")]
    public ActionResult Cancel(string orderId)
    {
        // 1. Remove the orderId from the database.
        return Json("Cancel", JsonRequestBehavior.AllowGet);
    }

    /// <summary>
    /// This action is called once the PayPal transaction is complete
    /// </summary>
    /// <param name="orderId"></param>
    /// <returns></returns>
    //[Route("api/paypal/checkout/order/error/{orderId}/{error}")]
    public ActionResult Error(string orderId,
                               string error)
    {
        // Log the error.
        // Notify the user.
        string temp = System.Web.HttpUtility.UrlDecode(error);
        return Json(temp, JsonRequestBehavior.AllowGet);
    }
}

public static class OrderBuilder
{
    /// <summary>
    /// Use classes from the PayPalCheckoutSdk to build an OrderRequest
    /// </summary>
    /// <returns></returns>
    public static OrderRequest Build()
    {
        // Construct a request object and set desired parameters
        // Here, OrdersCreateRequest() creates a POST request to /v2/checkout/orders
        OrderRequest order = new OrderRequest()
        {
            CheckoutPaymentIntent = "CAPTURE",
            PurchaseUnits = new List<PurchaseUnitRequest>()
                {
                    new PurchaseUnitRequest()
                    {
                        AmountWithBreakdown = new AmountWithBreakdown()
                        {
                            CurrencyCode = "USD",
                            Value = "100.00"
                        }
                    }
                },
            ApplicationContext = new ApplicationContext()
            {
                ReturnUrl = "https://www.example.com",
                CancelUrl = "https://www.example.com"
            }
        };


        // Call API with your client and get a response for your call
        var request = new OrdersCreateRequest();
        request.Prefer("return=representation");
        request.RequestBody(order);
        return order;
    }
}

public class PayPalClient
{

    public static string ClientId = " your client id";
    public static string Secrets = "your client secret";
    public static string SandboxClientId { get; set; } =
                         "<alert>{SandboxClientId}</alert>";
    public static string SandboxClientSecret { get; set; } =
                         "<alert>{SandboxClientSecret}</alert>";

    public static string LiveClientId { get; set; } =
                  "<alert>{PayPal LIVE Client Id}</alert>";
    public static string LiveClientSecret { get; set; } =
                  "<alert>{PayPal LIVE Client Secret}</alert>";


    public static PayPalEnvironment Environment()
    {
        //return new SandboxEnvironment("<alert>SandboxClientId</alert>",
        //                              "<alert>SandboxClientSecret</alert>");
        return new SandboxEnvironment(ClientId, Secrets);
    }
    public static PayPalCheckoutSdk.Core.PayPalHttpClient Client()
    {
        return new PayPalHttpClient(Environment());
    }

    public static PayPalCheckoutSdk.Core.PayPalHttpClient Client(string refreshToken)
    {
        return new PayPalHttpClient(Environment(), refreshToken);
    }

    public static String ObjectToJSONString(Object serializableObject)
    {
        MemoryStream memoryStream = new MemoryStream();
        var writer = JsonReaderWriterFactory.CreateJsonWriter(memoryStream,
                                                              Encoding.UTF8,
                                                              true,
                                                              true,
                                                              "  ");

        var ser = new DataContractJsonSerializer(serializableObject.GetType(),
                                             new DataContractJsonSerializerSettings
                                             {
                                                 UseSimpleDictionaryFormat = true
                                             });

        ser.WriteObject(writer,
                        serializableObject);

        memoryStream.Position = 0;
        StreamReader sr = new StreamReader(memoryStream);

        return sr.ReadToEnd();
    }
}

public class SmartButtonHttpResponse
{
    readonly PayPalCheckoutSdk.Orders.Order _result;
    public SmartButtonHttpResponse(PayPalHttp.HttpResponse httpResponse)
    {
        Headers = httpResponse.Headers;
        StatusCode = httpResponse.StatusCode;
        _result = httpResponse.Result<PayPalCheckoutSdk.Orders.Order>();
    }

    public HttpHeaders Headers { get; }
    public HttpStatusCode StatusCode { get; }

    public PayPalCheckoutSdk.Orders.Order Result()
    {
        return _result;
    }

    public string orderID { get; set; }
}





View html is

<!-- Set up a container element for the PayPal smart button -->
<div id="paypal-button-container"></div>
@section scripts
{
<script src="https://www.paypal.com/sdk/js?client-id=@ViewBag.ClientId"></script>
<script type="text/javascript">
       

        var orderId;
    function httpGet(url) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open("GET", url, false);
        xmlHttp.send(null);
        return xmlHttp.responseText;
    }
       
    paypal.Buttons({
        // Set up the transaction
        enableStandardCardFields: true,
        createOrder: function (data, actions) {
            orderId = data.orderID;
            console.log("Start");
            console.log(data);
            console.log(actions);
            console.log("End");
            return fetch(
                '/PaypalPayments/create/', {
                method: 'post'
            }).then(function (res) {
                return res.json();
            }).then(function (data) {
                return data.orderID;
            });
        },

        // Finalise the transaction
        onApprove: function (data, actions) {
            return fetch('/PaypalPayments/approved/' + data.orderID, {
                method: 'post'
            }).then(function (res) {
                return actions.order.capture();
            }).then(function (details) {

                // (Preferred) Notify the server that the transaction id complete
                // and have an option to display an order completed screen.
                window.location.replace('/PaypalPayments/complete/' +
                                         data.orderID + '/@ViewBag.CurrencyCode');

                // OR
                // Notify the server that the transaction id complete
                //httpGet('/api/paypal/checkout/order/complete/' + data.orderID);

                // Show a success message to the buyer
                alert('Transaction completed by ' + details.payer.name.given_name + '!');
            });
        },

        // Buyer cancelled the payment
        onCancel: function (data, actions) {
            httpGet('/PaypalPayments/cancel/' + data.orderID);
        },

        // An error occurred during the transaction
        onError: function (err) {
            debugger;
            fetch(
                '/PaypalPayments/error/', {
                    method: 'post',
                    headers: { 'Content-type': 'application/json' },
                    body: JSON.stringify({ orderId: orderId, error: encodeURIComponent(err)})
            }).then(function (res) {
                return res.json();
            }).then(function (data) {
                return data.orderID;
            });           
        }

    }).render('#paypal-button-container');

</script>
}

The error which I 'll have to receive is given below: My create post request is successful by returning 200 status.

After this request, the control instantly goes to Error function and throwing this error.

Error: Unexpected token P in JSON at position 0"

The complete error detail is mentioned below

SyntaxError: Unexpected token P in JSON at position 0

Error: Unexpected token P in JSON at position 0
    at Qt.error (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:60544)
    at Object.<anonymous> (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68311)
    at JSON.parse (<anonymous>)
    at o (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68170)
    at dr (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68323)
    at u.on (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:72994)
    at br (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:73131)
    at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79250
    at Function.n.try (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:14118)
    at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79047

Error: Unexpected token P in JSON at position 0
    at Qt.error (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:60544)
    at Array.<anonymous> (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68311)
    at JSON.parse (<anonymous>)
    at o (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68170)
    at dr (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:68323)
    at u.on (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:72994)
    at br (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:73131)
    at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79250
    at Function.n.try (https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:14118)
    at https://www.paypal.com/sdk/js?client-id=ATiT9hZAk22xK68Sg9cE3qg24jH1GP9eTm6XW2O47fPl3cligEblR35E1f24OnLg8XOmD7Y_tcnHDhPZ:2:79047

Can anybody guide me properly? I tried different articles but I am still getting these errors.

When you fetch /PaypalPayments/create/ from your server , what do you get back?

Obviously you aren't getting back valid JSON, but your code is trying to parse it as JSON.

Change your server code to only give back valid JSON. The code actually seems okay, so perhaps there is something wrong with the /PayPalPayments/create/ route that is hardcoded in the client-side code.

It would also be wise to change your client-side code to follow the best sample available, which is at https://developer.paypal.com/demo/checkout/#/pattern/server and demonstrates how to properly handle errors for the capture

(Just noticed the code in your example uses actions.order.capture() combined with this server-side integration, which is rather awful -- seems the server-side captureOrder task never even gets called, which is rather the whole point of using server-side APIs in the first place, if you don't capture from the server you get none of the benefits)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM