This repository has been archived by the owner on Jan 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
440 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Line ending normalization. ------------------------- | ||
# Reference https://help.github.com/articles/dealing-with-line-endings/ | ||
# Set the default behavior, in case people don't have core.autocrlf set. | ||
* text=auto | ||
|
||
# Explicitly declare text files you want to always be normalized and converted to native line endings on checkout. | ||
*.inc text | ||
*.ini text | ||
*.txt text | ||
*.xml text | ||
|
||
# Declare files that will always have LF line endings on checkout. | ||
.htaccess text eol=lf | ||
*.css text eol=lf | ||
*.htm text eol=lf | ||
*.html text eol=lf | ||
*.js text eol=lf | ||
*.json text eol=lf | ||
*.map text eol=lf | ||
*.md text eol=lf | ||
*.mo text eol=lf | ||
*.php text eol=lf | ||
*.po text eol=lf | ||
*.pot text eol=lf | ||
*.sql text eol=lf | ||
*.svg text eol=lf | ||
*.yml text eol=lf | ||
|
||
# Denote all files that are truly binary and should not be modified. | ||
*.eot binary | ||
*.gif binary | ||
*.ico binary | ||
*.jpeg binary | ||
*.jpg binary | ||
*.mp3 binary | ||
*.mp4 binary | ||
*.otf binary | ||
*.png binary | ||
*.swf binary | ||
*.ttf binary | ||
*.wav binary | ||
*.woff binary | ||
*.woff2 binary | ||
# End line ending normalization. ---------------------- | ||
|
||
# Export ignore folders, files. | ||
.gitattributes export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Options +Indexes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
|
||
date_default_timezone_set('Asia/Bangkok'); | ||
ini_set('error_reporting', E_ALL); | ||
ini_set('display_errors', true); | ||
|
||
|
||
/** | ||
* @link https://docs.lemonsqueezy.com/help/webhooks Document. | ||
* @var string Secret key that you create for use in web hook. | ||
*/ | ||
$key = ''; | ||
|
||
|
||
/** | ||
* @link https://docs.lemonsqueezy.com/guides/developer-guide/getting-started#create-an-api-key Document. | ||
* @var string API key created from Lemon Squeezy. | ||
*/ | ||
$LSAPI = ''; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
|
||
/** | ||
* Display debug about cURL result (path, HTTP status code, response headers, response body). | ||
* | ||
* @param string $URLPath The path that requested to the server. | ||
* @param int $responseStatus HTTP response code or status code. | ||
* @param array $responseHeaders Response headers. | ||
* @param string|bool $responseBody Response body. This should be string. | ||
*/ | ||
function debugCurlResult(string $URLPath, $responseStatus, array $responseHeaders, $responseBody) | ||
{ | ||
echo '<h3>Request URL path</h3>' . "\n"; | ||
echo '<p>' . htmlspecialchars($URLPath, ENT_QUOTES) . '</p>' . "\n"; | ||
|
||
echo '<h3>Response headers</h3>' . "\n"; | ||
echo '<p>HTTP status: ' . var_export($responseStatus, true) . ' (' . gettype($responseStatus) . ')</p>' . "\n"; | ||
if (is_array($responseHeaders)) { | ||
ksort($responseHeaders); | ||
} | ||
var_dump($responseHeaders); | ||
|
||
echo '<h3>Response body</h3>' . "\n"; | ||
if (is_string($responseBody)) { | ||
$resultJSO = json_decode($responseBody); | ||
} | ||
if (isset($resultJSO) && json_last_error() === JSON_ERROR_NONE) { | ||
echo '<h4>JSON object</h4>' . "\n"; | ||
echo '<pre>' . var_export($resultJSO, true) . '</pre>' . "\n"; | ||
} else { | ||
echo '<h4>JSON decode error</h4>' . "\n"; | ||
echo '<p>' . json_last_error_msg() . '</p>' . "\n"; | ||
echo '<h4>Raw result</h4>' . "\n"; | ||
echo '<pre>' . var_export($responseBody, true) . '</pre>' . "\n"; | ||
} | ||
unset($resultJSO); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
/** | ||
* Lemon Squeezy API. | ||
* | ||
* @link https://docs.lemonsqueezy.com/api Document. | ||
*/ | ||
|
||
|
||
require '_config.php'; | ||
require_once '_functions.php'; | ||
|
||
|
||
$APIURL = 'https://api.lemonsqueezy.com'; | ||
$requestHeaders = [ | ||
'Authorization: Bearer ' . $LSAPI, | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
hello |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
<?php | ||
/** | ||
* For demonstrate how "License API" work on Lemon Squeezy. | ||
* | ||
* Warning! This demo is not secure, you have to implement security feature such as XSS, CSRF protection yourself. | ||
* | ||
* @link https://docs.lemonsqueezy.com/help/licensing/license-api Document. | ||
*/ | ||
|
||
|
||
require __DIR__ . DIRECTORY_SEPARATOR . '/_ls_api.php'; | ||
|
||
|
||
if (isset($_SERVER['REQUEST_METHOD']) && strtoupper($_SERVER['REQUEST_METHOD']) === 'POST') { | ||
$licenseKey = ($_POST['license-key'] ?? ''); | ||
$btnAct = strtolower(($_POST['btn-act'] ?? 'validate')); | ||
|
||
// validate button action and then set URL path. | ||
if ($btnAct === 'activate') { | ||
$URLPath = '/v1/licenses/activate'; | ||
} elseif ($btnAct === 'validate') { | ||
$URLPath = '/v1/licenses/validate'; | ||
} elseif ($btnAct === 'deactivate') { | ||
$URLPath = '/v1/licenses/deactivate'; | ||
} | ||
|
||
if (isset($URLPath)) { | ||
// if there is validated button action and already set URL path. | ||
$ch = curl_init($APIURL . $URLPath); | ||
$responseHeaders = []; | ||
$data = []; | ||
$data['license_key'] = $licenseKey; | ||
if ($btnAct === 'activate') { | ||
$data['instance_name'] = 'license-key'; | ||
} elseif ($btnAct === 'deactivate') { | ||
$data['instance_id'] = ($_COOKIE['ls_licensing_' . $licenseKey . '_instid'] ?? ''); | ||
} | ||
$requestHeaders[] = 'Accept: application/json'; | ||
$requestHeaders[] = 'Content-Type: application/x-www-form-urlencoded'; | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
/** | ||
* @link https://stackoverflow.com/a/41135574/128761 Original source code. | ||
*/ | ||
curl_setopt( | ||
$ch, | ||
CURLOPT_HEADERFUNCTION, | ||
function ($curl, $header) use (&$responseHeaders) { | ||
$len = strlen($header); | ||
$header = explode(':', $header, 2); | ||
if (count($header) < 2) // ignore invalid headers | ||
return $len; | ||
|
||
$responseHeaders[strtolower(trim($header[0]))][] = trim($header[1]); | ||
|
||
return $len; | ||
} | ||
); | ||
$result = curl_exec($ch); | ||
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
curl_close($ch); | ||
unset($ch, $data, $requestHeaders); | ||
|
||
if ($btnAct === 'activate') { | ||
$resultJSO = json_decode($result); | ||
if (isset($resultJSO->instance->id)) { | ||
// if there is instance id in return. this is normal in activation process. | ||
// in your project, save this instance id somewhere more reliable than cookie. for example the database. | ||
// this instance id will be use in deactivation process. | ||
setcookie('ls_licensing_' . $licenseKey . '_instid', $resultJSO->instance->id, [ | ||
'path' => '/', | ||
'expires' => time() + (366 * 86400), | ||
]); | ||
} | ||
unset($resultJSO); | ||
} elseif ($btnAct === 'deactivate') { | ||
setcookie('ls_licensing_' . $licenseKey . '_instid', '', [ | ||
'path' => '/', | ||
'expires' => time() - (366 * 86400), | ||
]); | ||
}// endif button action after cURL response. | ||
}// endif; validate button action and set URL path. | ||
|
||
unset($btnAct, $licenseKey); | ||
}// endif; method POST | ||
?> | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Lemon Squeezy License API</title> | ||
<style> | ||
button { | ||
padding: 5px; | ||
} | ||
code { | ||
background-color: #eee; | ||
color: #bb6800; | ||
padding: 2px 4px; | ||
} | ||
input { | ||
min-width: 260px; | ||
padding: 5px; | ||
} | ||
pre { | ||
background-color: #eee; | ||
color: #222; | ||
margin: 0; | ||
padding: 10px; | ||
white-space: pre-wrap; | ||
word-break: break-all; | ||
word-wrap: break-word; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Lemon Squeezy License API</h1> | ||
<form method="post"> | ||
<input type="text" name="license-key" value="<?php if (isset($_POST['license-key'])) {echo htmlspecialchars($_POST['license-key'], ENT_QUOTES);} ?>" placeholder="License key"> | ||
<p> | ||
<button type="submit" name="btn-act" value="activate">Activate</button> | ||
<button type="submit" name="btn-act" value="validate">Validate</button> | ||
<button type="submit" name="btn-act" value="deactivate">Deactivate</button> | ||
</p> | ||
<p>Use <strong>Activate</strong> button to activate the license key.</p> | ||
<p>Use <strong>Validate</strong> button to validate the license key. The return result should be <code>'status' => 'active'</code> and <code>activation_usage</code>, <code>expires_at</code> should be valid.</p> | ||
</form> | ||
<?php | ||
if (isset($URLPath) && isset($httpStatus) && isset($responseHeaders) && isset($result)) { | ||
echo '<h2>Result</h2>' . "\n"; | ||
debugCurlResult($URLPath, $httpStatus, $responseHeaders, $result); | ||
unset($httpStatus, $responseHeaders, $result, $URLPath); | ||
} | ||
?> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
<?php | ||
/** | ||
* For testing that Lemon Squeezy API works. | ||
*/ | ||
|
||
|
||
require __DIR__ . DIRECTORY_SEPARATOR . '/_ls_api.php'; | ||
|
||
|
||
$URLPath = '/v1/stores'; | ||
$ch = curl_init($APIURL . $URLPath); | ||
$responseHeaders = []; | ||
$requestHeaders[] = 'Accept: application/vnd.api+json'; | ||
$requestHeaders[] = 'Content-Type: application/vnd.api+json'; | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, $requestHeaders); | ||
// if you use other method than GET, POST. set it below this line. | ||
//curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET'); | ||
// in case you have to send POST data, use option below. | ||
// also required header `Content-Type: application/x-www-form-urlencoded` to work with `http_build_query()`. | ||
//curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(['name' => 'value']));// | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
/** | ||
* @link https://stackoverflow.com/a/41135574/128761 Original source code. | ||
*/ | ||
curl_setopt( | ||
$ch, | ||
CURLOPT_HEADERFUNCTION, | ||
function ($curl, $header) use (&$responseHeaders) { | ||
$len = strlen($header); | ||
$header = explode(':', $header, 2); | ||
if (count($header) < 2) // ignore invalid headers | ||
return $len; | ||
|
||
$responseHeaders[strtolower(trim($header[0]))][] = trim($header[1]); | ||
|
||
return $len; | ||
} | ||
); | ||
$result = curl_exec($ch); | ||
$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE); | ||
curl_close($ch); | ||
unset($ch, $requestHeaders); | ||
|
||
|
||
debugCurlResult($URLPath, $httpStatus, $responseHeaders, $result); | ||
unset($httpStatus, $responseHeaders, $result, $URLPath); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Lemon Squeezy web hooks and API demo. | ||
This repository will show you how web hooks and "License API" work with Lemon Squeezy. | ||
|
||
Required PHP 7.0 or newer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
/** | ||
* Receive hooks for debugging. | ||
* | ||
* Make Lemon Squeezy web hook call back URL to this file. | ||
* Example: make callback to https://thisdomain.tld/app/receive-hook.php | ||
* | ||
* @link https://docs.lemonsqueezy.com/help/webhooks Document. | ||
*/ | ||
|
||
|
||
require __DIR__ . '/_config.php'; | ||
|
||
|
||
$log = '[' . date('Y-m-d H:i:s') . ']'; | ||
$log .= "\tHeaders:" . normalizeString(var_export(getallheaders(), true)) . ';' . "\n"; | ||
$log .= "\tGET:" . normalizeString(var_export($_GET, true)) . ';' . "\n"; | ||
$log .= "\tPOST:" . normalizeString(var_export($_POST, true)) . ';' . "\n"; | ||
ksort($_SERVER); | ||
$log .= "\tSERVER:" . normalizeString(var_export($_SERVER, true)) . ';' . "\n"; | ||
|
||
|
||
if (isset($_SERVER['HTTP_X_SIGNATURE'])) { | ||
// if there is signature. | ||
// @link https://docs.lemonsqueezy.com/help/webhooks#signing-requests signing requests API doc. | ||
$payload = file_get_contents('php://input'); | ||
$hash = hash_hmac('sha256', $payload, $key); | ||
$signature = ($_SERVER['HTTP_X_SIGNATURE'] ?? ''); | ||
$log .= "\tPHP://input:" . normalizeString(var_export($payload, true)) . ';' . "\n"; | ||
$JSOPayload = json_decode($payload); | ||
if (json_last_error() === JSON_ERROR_NONE) { | ||
$log .= "\tJSON object of PHP://input:" . normalizeString(var_export($JSOPayload, true)) . ';' . "\n"; | ||
} | ||
$log .= "\tHash equals:" . normalizeString(var_export(hash_equals($hash, $signature), true)) . ';' . "\n"; | ||
unset($hash, $JSOPayload, $payload, $signature); | ||
} | ||
$eventName = str_replace(' ', '-', ($_SERVER['HTTP_X_EVENT_NAME'] ?? 'EVENTUNKNOWN')); | ||
|
||
$log .= "\n\n\n\n"; | ||
|
||
file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'debug_' . basename(__FILE__, '.php') . '_event-' . $eventName . '_' . date('YmdHis') . '.txt', $log, FILE_APPEND); | ||
unset($eventName); | ||
|
||
|
||
// end receive hooks debugging. ============================================== | ||
|
||
|
||
/** | ||
* Normalize string. | ||
* | ||
* @param string $string The input string | ||
* @return string Return normalized string. | ||
*/ | ||
function normalizeString(string $string): string | ||
{ | ||
$string = str_replace(["\r\n", "\r"], "\n", $string);// make unix new line only. | ||
$string = preg_replace('/(\h{2,})/', ' ', $string);// make multiple horizontal spaces to be one. | ||
$string = preg_replace('/^(\h*)/m', "\t$1", $string);// prepend tab at beginning of line. | ||
return trim($string); | ||
} |
Oops, something went wrong.