"client_credentials", ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($payload)); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/x-www-form-urlencoded", "Authorization: Basic " . base64_encode(PAYPAL_CLIENT_ID . ":" . PAYPAL_CLIENT_SECRET), // Uncomment one of these to force an error for negative testing (in sandbox mode only). ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Further processing ... if ($response_code === 200) { return json_decode($response)->access_token; } else { header("Content-Type: application/json"); http_response_code($response_code); echo $response; die(); } } /** * Create an order to start the transaction. * * @see https://developer.paypal.com/docs/api/orders/v2/#orders_create * @param array $cart * @return array */ function createOrder($cart) { try { $access_token = generateAccessToken(); if (!$access_token) { http_response_code(500); header("Content-Type: application/json"); echo json_encode(["error" => "Failed to obtain access token."]); die(); } $url = PAYPAL_BASE_URL . "/v2/checkout/orders"; $payload = [ "intent" => "CAPTURE", "purchase_units" => [ [ "amount" => [ "currency_code" => $cart[0]->unit_amount->currency_code, "value" => $cart[0]->unit_amount->value, "breakdown" => [ "item_total" => [ "currency_code" => $cart[0]->unit_amount->currency_code, "value" => $cart[0]->unit_amount->value, ], ], ], "items" => [ [ "name" => $cart[0]->description, "description" => $cart[0]->description, "unit_amount" => [ "currency_code" => $cart[0]->unit_amount->currency_code, "value" => $cart[0]->unit_amount->value, ], "quantity" => 1, ], ], ], ], ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", "Authorization: Bearer $access_token", ]); // Uncomment one of these to force an error for negative testing (in sandbox mode only). // Documentation: https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/ // 'PayPal-Mock-Response' => '{"mock_application_codes": "MISSING_ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Further processing ... if ($response_code === 200) { header("Content-Type: application/json"); http_response_code($response_code); echo $response; die(); } else { header("Content-Type: application/json"); http_response_code($response_code); echo $response; die(); } } catch (\Exception $error) { header("Content-Type: application/json"); http_response_code(500); echo json_encode(["error" => "Failed to create order."]); die(); } } /** * Capture payment for the given order * * @see https://developer.paypal.com/docs/api/orders/v2/#orders_capture * @param array $cart * @return array */ function captureOrder($order_id) { $url = PAYPAL_BASE_URL . "/v2/checkout/orders/{$order_id}/capture"; // Http::fake(function ($request) { // // Capture and log request headers // $headers = $request->headers(); // // Log headers for inspection // \Log::info('Captured Request Headers', $headers); // return Http::response('', 200, [ // 'X-Custom-Response-Header' => 'HeaderValue' // ]); // }); $auth = base64_encode(PAYPAL_CLIENT_ID . ":" . PAYPAL_CLIENT_SECRET); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", "Authorization: Basic $auth", ]); // Uncomment one of these to force an error for negative testing (in sandbox mode only). // Documentation: https://developer.paypal.com/tools/sandbox/negative-testing/request-headers/ // 'PayPal-Mock-Response' => '{"mock_application_codes": "MISSING_ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // Further processing ... if ($response_code === 200) { header("Content-Type: application/json"); http_response_code($response_code); echo $response; die(); } else { header("Content-Type: application/json"); http_response_code($response_code); echo $response; die(); } } if ( $_SERVER["REQUEST_METHOD"] === "POST" && $_SERVER["REQUEST_URI"] === "/api/orders" ) { $body = file_get_contents("php://input"); $cart = json_decode($body)->cart; createOrder($cart); } if ($_SERVER["REQUEST_METHOD"] === "POST") { $order_id = substr($_SERVER["REQUEST_URI"], 12, 17); captureOrder($order_id); } if ($_SERVER["REQUEST_METHOD"] !== "POST") { http_response_code(404); die(); }