1
0
Fork 0
app.sixfold.org/www/games/process-order.php

234 lines
7.5 KiB
PHP

<?php
/**
* Generate an OAuth 2.0 access token for authenticating with PayPal REST APIs.
*
* @see https://developer.paypal.com/api/rest/authentication/
* @return string|null
*/
function generateAccessToken()
{
if (!PAYPAL_CLIENT_ID || !PAYPAL_CLIENT_SECRET) {
throw new \Exception("MISSING_API_CREDENTIALS");
}
$url = PAYPAL_BASE_URL . "/v1/oauth2/token";
$payload = [
"grant_type" => "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)
{
$game_id = $_POST["game_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 || $response_code === 201) {
header("Content-Type: application/json");
$order_data = json_decode($response);
http_response_code($response_code);
$transaction_id =
$order_data->purchase_units[0]->payments->captures[0]->id ??
($order_data->purchase_units[0]->payments->authorizations[0]->id ??
"_");
update_submission($game_id, $transaction_id);
echo $response;
die();
} else {
header("Content-Type: application/json");
http_response_code($response_code);
echo $response;
die();
}
}
/**
* @param string game_id
* @param string transaction_id
*/
function update_submission($game_id, $transaction_id)
{
global $db;
$sql = "UPDATE submissions SET transaction_id = :transaction_id
WHERE game_id = :game_id AND member_id = :member_id";
$stmt = $db["data"]->prepare($sql);
$stmt->execute([
"game_id" => $game_id,
"member_id" => $_SESSION["account"]->id,
"transaction_id" => $transaction_id,
]);
}
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();
}