I am trying to integrate PayPal Smart buttons in my Laravel 8 Website. These are the documentation I am using: https://developer.paypal.com/docs/checkout/integrate/
https://developer.paypal.com/docs/checkout/reference/server-integration/set-up-transaction/
https://github.com/paypal/Checkout-PHP-SDK
Issue: I get two errors:
This error underlines the fetch in my front-end.
cart:278 POST http://127.0.0.1:8000/createOrder 500 (Internal Server Error)
{err: "Error: Expected an order id to be passed↵
Here is my route file:
use AppHttpControllersPayPalController; Route::post('/createOrder', [PayPalController::class, 'createOrder']);
Here is my PayPalController Method:
<?php namespace AppHttpControllers; // To capture payment for paypal namespace SampleCaptureIntentExamples; // Grabs the environment and request to be used for paypal use SamplePayPalClient; use PayPalCheckoutSdkOrdersOrdersCreateRequest; // Request/Response use IlluminateHttpRequest; use IlluminateHttpResponse; class PayPalController extends Controller { public function createOrder() { $request = new OrdersCreateRequest(); $request->prefer('return=representation'); $request->body = [ "intent" => "CAPTURE", "purchase_units" => [[ "reference_id" => "test_ref_id1", "amount" => [ "value" => "100.00", "currency_code" => "USD" ] ]], "application_context" => [ "cancel_url" => "https://127.0.0.1:8000/cart", "return_url" => "https://127.0.0.1:8000/" ] ]; // 3. Call PayPal to set up a transaction $client = PayPalClient::client(); $response = $client->execute($request); // 4. Return a successful response to the client. return $response; } }
Here is my front-end .blade.view file:
<script src="https://www.paypal.com/sdk/js?client-id=*******************"></script> <form action="/createOrder" method="POST"> @csrf <div id="paypal-button-container"></div> <script> paypal.Buttons({ createOrder: function() { return fetch('/createOrder', { method: 'POST', headers: { 'content-type': 'application/json', 'Accept': 'application/json', 'url': '/createOrder', "X-CSRF-Token": document.querySelector('input[name=_token]').value }, }).then(function(res) { return res.json(); }).then(function(data) { return data.orderID; // Use the same key name for order ID on the client and server }); } }).render('#paypal-button-container'); </script> </form>
I have edited the PayPalClient.php file with my credentials.
Advertisement
Answer
A 500 error within your /createOrder route is something you’ll need to diagnose/debug internally. Try loading the URL in a browser and see if you get any more error output from Laravel. If you don’t, edit the corresponding PHP to output more useful information about what’s going on.
Once you sort that out and are returning an actual id
as part of a JSON object, you need to change your front end code to read the key of that id
. It looks like you are reading the key orderID
, which won’t be set unless you specifically set it.
The following front-end demo code is better, and has error handling: https://developer.paypal.com/demo/checkout/#/pattern/server
This part of your front-end code:
<form action="/createOrder" method="POST">
Makes absolutely no sense, unless it’s just for testing purposes, but still really doesn’t make sense.
All you should have is a container <div>
with the id paypal-button-container
, for the JS to render its own button in. That button does not in any way use or work with an HTML form.