Fix PM+Cert+#10 env label image bug, update super old everything (Stripe/EasyPost/PHPMailer), add Sentry/GlitchTip error monitoring, add test mode domain

This commit is contained in:
Skylar Ittner 2026-03-24 15:18:52 -06:00
parent e84605bc45
commit d4233311e5
14 changed files with 1054 additions and 153 deletions

View File

@ -2,4 +2,6 @@ sass source/static/assets/sass/main.scss source/static/assets/css/main.css
php bin/compile.php php bin/compile.php
rsync -rv --exclude=settings.php web webhost.netsyms.net:/var/www/certifiedfromhome.com/ rsync -rv web webhost.netsyms.net:/var/www/test.certifiedfromhome.com/
#rsync -rv --exclude=settings.php web webhost.netsyms.net:/var/www/certifiedfromhome.com/

View File

@ -2,7 +2,8 @@
"context": { "context": {
"site_title": "Certified from Home", "site_title": "Certified from Home",
"site_root": "https://certifiedfromhome.com/", "site_root": "https://certifiedfromhome.com/",
"stripe_pk": "pk_live_51NEHz0LeSU0ahZ9MUVOnCSGAibY3M4UHqdRzdxFLMnlmbnMAVJzDz0psztY9AvwpTjRcpXkJT5ljBaY7z6v0w2TT00dA0Lnx2d", "stripe_pk_live": "pk_live_51NEHz0LeSU0ahZ9MUVOnCSGAibY3M4UHqdRzdxFLMnlmbnMAVJzDz0psztY9AvwpTjRcpXkJT5ljBaY7z6v0w2TT00dA0Lnx2d",
"stripe_pk_test": "pk_test_51NEHz0LeSU0ahZ9MpX1WyzQWkJLvSntsj181vTRXLVqJqdZcQ7i7rLpNu7X6iinaIq1h8UOz4Ypkzh61RZ06CXIs00UhIjvV1M",
"navigation": [ "navigation": [
{ {
"title": "Home", "title": "Home",

View File

@ -3,8 +3,7 @@
<div class="copyright"> <div class="copyright">
<a href="{{site_root}}refunds">Refund Policy and Instructions</a> <a href="{{site_root}}refunds">Refund Policy and Instructions</a>
<br /> <br />
&copy; 2021-2025 <a href="https://postalportal.net">PostalPortal LLC</a>.<br> &copy; 2021-2026 <a href="https://postalportal.net">PostalPortal LLC</a> with help from <a href="https://netsyms.com">Netsyms Technologies</a>.
Developed and hosted by <a href="https://netsyms.com">Netsyms Technologies</a>.
<br /> <br />
<a href="https://postalportal.net/#contact">Contact Us</a> <a href="https://postalportal.net/#contact">Contact Us</a>
</div> </div>

View File

@ -3,9 +3,9 @@
<title>{{#title}}{{title}} :: {{/title}}{{site_title}}</title> <title>{{#title}}{{title}} :: {{/title}}{{site_title}}</title>
<link rel="stylesheet" href="{{site_root}}assets/css/main.css" /> <link rel="stylesheet" href="/assets/css/main.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="{{site_root}}/assets/favicon.png"> <link rel="icon" href="/assets/favicon.png">
<meta property="og:title" content="{{#title}}{{title}} :: {{/title}}{{site_title}}" /> <meta property="og:title" content="{{#title}}{{title}} :: {{/title}}{{site_title}}" />
<meta property="og:url" content="{{site_root}}" /> <meta property="og:url" content="{{site_root}}" />

View File

@ -1,12 +1,7 @@
<script src="https://static.netsyms.net/jquery/jquery.min.js"></script> <script src="https://static.netsyms.net/jquery/jquery.min.js"></script>
<script src="{{site_root}}assets/js/browser.min.js"></script> <script src="/assets/js/browser.min.js"></script>
<script src="{{site_root}}assets/js/breakpoints.min.js"></script> <script src="/assets/js/breakpoints.min.js"></script>
<script src="{{site_root}}assets/js/util.js"></script> <script src="/assets/js/util.js"></script>
<script src="{{site_root}}assets/js/jquery.scrollex.min.js"></script> <script src="/assets/js/jquery.scrollex.min.js"></script>
<script src="{{site_root}}assets/js/jquery.scrolly.min.js"></script> <script src="/assets/js/jquery.scrolly.min.js"></script>
<script src="{{site_root}}assets/js/main.js"></script> <script src="/assets/js/main.js"></script>
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe = Stripe("{{stripe_pk}}");
</script>
<script src="{{site_root}}assets/js/shipment.js"></script>

View File

@ -276,7 +276,7 @@
<li><a id="startOverButton" class="button large icon regular fa-redo">Send Another Letter</a></li> <li><a id="startOverButton" class="button large icon regular fa-redo">Send Another Letter</a></li>
</ul> </ul>
<iframe style="width: 100%; height: 1200px; max-height:80vh;" src="about:blank" id="pdfframe"></iframe> <iframe style="width: 100%; height: 1200px; max-height:80vh;" src="about:blank" id="pdfframe"></iframe>
<a id="pdfbackuplink">Can't see the file and/or print it? Click here.</a> <a id="pdfbackuplink" style="cursor: pointer;">Can't see the file and/or print it? Click here.</a>
</div> </div>
</div> </div>
</section> </section>
@ -284,5 +284,10 @@
{{> footer}} {{> footer}}
</div> </div>
{{> scripts}} {{> scripts}}
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe = Stripe((window.location.hostname == "test.certifiedfromhome.com" ? "{{stripe_pk_test}}" : "{{stripe_pk_live}}"));
</script>
<script src="/assets/js/shipment.js"></script>
</body> </body>
</html> </html>

View File

@ -117,7 +117,7 @@ function submitPayment() {
"no10_envelope": document.getElementById('no10_envelope').checked ? "1" : "" "no10_envelope": document.getElementById('no10_envelope').checked ? "1" : ""
}, },
dataType: "json", dataType: "json",
timeout: 1000 * 30, timeout: 1000 * 60,
success: function (resp) { success: function (resp) {
if (resp.status == "OK") { if (resp.status == "OK") {
// load PDF to print // load PDF to print

View File

@ -1,10 +1,10 @@
{ {
"name": "netsyms/www", "name": "netsyms/www",
"require": { "require": {
"phpmailer/phpmailer": "^6.0", "phpmailer/phpmailer": "^7.0",
"stripe/stripe-php": "^7.71", "stripe/stripe-php": "^19",
"catfan/medoo": "^1.7", "easypost/easypost-php": "^8",
"easypost/easypost-php": "^3.4" "sentry/sdk": "^4.0"
}, },
"authors": [ "authors": [
{ {

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ try {
throw new Exception("Please enter your email address. We use it to send you a receipt with your tracking number and other info. You won't get any spam emails, we promise."); throw new Exception("Please enter your email address. We use it to send you a receipt with your tracking number and other info. You won't get any spam emails, we promise.");
} }
$shipmentinfo["from_address"] = \EasyPost\Address::create([ $shipmentinfo["from_address"] = $easypostClient->address->create([
"verify" => array("delivery"), "verify" => array("delivery"),
"name" => $_REQUEST["from_name"], "name" => $_REQUEST["from_name"],
"street1" => $_REQUEST["from_street"], "street1" => $_REQUEST["from_street"],
@ -42,7 +42,7 @@ try {
"country" => "US" "country" => "US"
]); ]);
$shipmentinfo["to_address"] = \EasyPost\Address::create([ $shipmentinfo["to_address"] = $easypostClient->address->create([
"verify" => array("delivery"), "verify" => array("delivery"),
"name" => $_REQUEST["to_name"], "name" => $_REQUEST["to_name"],
"company" => $_REQUEST["to_company"], "company" => $_REQUEST["to_company"],
@ -81,12 +81,12 @@ try {
if (!empty($_REQUEST["no10_envelope"]) && $_REQUEST["no10_envelope"] == "no10_envelope") { if (!empty($_REQUEST["no10_envelope"]) && $_REQUEST["no10_envelope"] == "no10_envelope") {
throw new Exception("You can't use your own envelope with Priority Mail Flat Rate. Use a USPS-provided Flat Rate envelope instead."); throw new Exception("You can't use your own envelope with Priority Mail Flat Rate. Use a USPS-provided Flat Rate envelope instead.");
} }
$shipmentinfo["parcel"] = \EasyPost\Parcel::create([ $shipmentinfo["parcel"] = $easypostClient->parcel->create([
"predefined_package" => "FlatRateEnvelope", "predefined_package" => "FlatRateEnvelope",
"weight" => $weight "weight" => $weight
]); ]);
} else { } else {
$shipmentinfo["parcel"] = \EasyPost\Parcel::create([ $shipmentinfo["parcel"] = $easypostClient->parcel->create([
"predefined_package" => "Letter", "predefined_package" => "Letter",
"weight" => $weight "weight" => $weight
]); ]);
@ -142,7 +142,7 @@ try {
$shipmentinfo["options"]["label_date"] = $mailing_date; $shipmentinfo["options"]["label_date"] = $mailing_date;
$shipment = \EasyPost\Shipment::create($shipmentinfo); $shipment = $easypostClient->shipment->create($shipmentinfo);
$selectedrate = []; $selectedrate = [];
for ($i = 0; $i < count($shipment->rates); $i++) { for ($i = 0; $i < count($shipment->rates); $i++) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -26,9 +26,9 @@
borderopacity="1.0" borderopacity="1.0"
inkscape:pageopacity="1" inkscape:pageopacity="1"
inkscape:pageshadow="2" inkscape:pageshadow="2"
inkscape:zoom="0.98994949" inkscape:zoom="0.49497475"
inkscape:cx="448.00266" inkscape:cx="333.35034"
inkscape:cy="112.63201" inkscape:cy="359.61431"
inkscape:document-units="in" inkscape:document-units="in"
inkscape:current-layer="layer2" inkscape:current-layer="layer2"
showgrid="false" showgrid="false"
@ -36,8 +36,8 @@
inkscape:measure-start="24,480" inkscape:measure-start="24,480"
inkscape:measure-end="24,336" inkscape:measure-end="24,336"
inkscape:window-width="1920" inkscape:window-width="1920"
inkscape:window-height="1015" inkscape:window-height="1008"
inkscape:window-x="1920" inkscape:window-x="0"
inkscape:window-y="0" inkscape:window-y="0"
inkscape:window-maximized="1" inkscape:window-maximized="1"
showguides="false" showguides="false"
@ -79,8 +79,8 @@
sodipodi:role="line">USPS CERTIFIED MAIL™</tspan></text></g></g></g><g sodipodi:role="line">USPS CERTIFIED MAIL™</tspan></text></g></g></g><g
inkscape:groupmode="layer" inkscape:groupmode="layer"
id="layer2" id="layer2"
inkscape:label="Layer 2" inkscape:label="Preview"
style="display:inline"><image style="display:none"><image
width="101.6" width="101.6"
height="152.39999" height="152.39999"
preserveAspectRatio="none" preserveAspectRatio="none"

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -6,12 +6,14 @@ $shipmentinfo = [];
try { try {
$shipment = \EasyPost\Shipment::retrieve($_REQUEST["shipmentid"]); $shipment = $easypostClient->shipment->retrieve($_REQUEST["shipmentid"]);
$price = 0; $price = 0;
$cost = 0; $cost = 0;
$selectedRate = null;
foreach ($shipment->rates as $rate) { foreach ($shipment->rates as $rate) {
if ($rate->id == $_REQUEST["rateid"]) { if ($rate->id == $_REQUEST["rateid"]) {
$selectedRate = $rate;
$cost = $rate->rate; $cost = $rate->rate;
$retail_rate = $rate->retail_rate ?? ($rate->list_rate ?? $rate->rate); $retail_rate = $rate->retail_rate ?? ($rate->list_rate ?? $rate->rate);
$price = $retail_rate + 1.00; $price = $retail_rate + 1.00;
@ -27,7 +29,7 @@ try {
} }
// make the payment intent but don't capture it yet, in case something goes wrong. // make the payment intent but don't capture it yet, in case something goes wrong.
$intent = \Stripe\PaymentIntent::create([ $intent = $stripeClient->paymentIntents->create([
'amount' => $price * 100, 'amount' => $price * 100,
'currency' => 'usd', 'currency' => 'usd',
'payment_method' => $_REQUEST["stripeid"], 'payment_method' => $_REQUEST["stripeid"],
@ -63,14 +65,13 @@ try {
if (empty($shipment->postage_label)) { if (empty($shipment->postage_label)) {
// Do this conditionally in case label got purchased but payment somehow failed, // Do this conditionally in case label got purchased but payment somehow failed,
// allowing a retry of the payment. // allowing a retry of the payment.
$shipment->buy(['rate' => ['id' => $_REQUEST["rateid"]]]); $shipment = $easypostClient->shipment->buy($shipment->id, $selectedRate);
} }
$pdffile = date("Ymd") . "_" . hash("sha256", $shipment->id) . ".pdf"; $pdffile = date("Ymd") . "_" . hash("sha256", $shipment->id) . ".pdf";
try { try {
$stripe = new \Stripe\StripeClient($_SETTINGS["stripe_sk"]); $stripeClient->paymentIntents->update($intent->id, [
$stripe->paymentIntents->update($intent->id, [
"metadata" => [ "metadata" => [
"tracking_number" => "$shipment->tracking_code", "tracking_number" => "$shipment->tracking_code",
"from_email" => (empty($shipment->from_address->email) ? "None" : $shipment->from_address->email . ""), "from_email" => (empty($shipment->from_address->email) ? "None" : $shipment->from_address->email . ""),
@ -101,7 +102,7 @@ try {
$paperimage = imagecreatefrompng(__DIR__ . "/papertemplate_no10.png"); $paperimage = imagecreatefrompng(__DIR__ . "/papertemplate_no10.png");
} }
$labelimage = imagerotate($labelimage, 270, 0); $labelimage = imagerotate($labelimage, 270, 0);
imagecopyresampled($paperimage, $labelimage, 525, 19, 0, 0, 1200, 1800, 1200, 1800); imagecopyresampled($paperimage, $labelimage, 525, 19, 0, 0, 1800, 1200, 1800, 1200);
} else { } else {
if (!empty($shipment->options->certified_mail)) { if (!empty($shipment->options->certified_mail)) {
// envelope with banner // envelope with banner
@ -191,7 +192,7 @@ try {
$mail->setReplyTo($emailsettings["replyto"]); $mail->setReplyTo($emailsettings["replyto"]);
} }
$mail->addTo($shipment->from_address->email); $mail->addTo($shipment->from_address->email);
$mail->setSubject("Your CertifiedFromHome Receipt"); $mail->setSubject(($_SETTINGS["test"] ? "[TEST MODE] " : "") . "Your CertifiedFromHome Receipt");
$body = "Thanks for using CertifiedFromHome.com!\r\nYour card has been charged a total of $" . number_format($price, 2) . ".\r\n"; $body = "Thanks for using CertifiedFromHome.com!\r\nYour card has been charged a total of $" . number_format($price, 2) . ".\r\n";
if (!empty($shipment->options->certified_mail)) { if (!empty($shipment->options->certified_mail)) {
$body .= "You can track your letter with this tracking code: " . $shipment->tracking_code . "\r\n"; $body .= "You can track your letter with this tracking code: " . $shipment->tracking_code . "\r\n";
@ -203,7 +204,7 @@ try {
. "scroll down and click on \"Return Receipt Electronic\", and fill in the form. USPS will " . "scroll down and click on \"Return Receipt Electronic\", and fill in the form. USPS will "
. "email you a PDF proof of delivery with the recipient's signature and other info.\r\n\r\n"; . "email you a PDF proof of delivery with the recipient's signature and other info.\r\n\r\n";
} }
$body .= "Here's a link to your purchased postage, just in case: https://certifiedfromhome.com/pdf/" . $pdffile $body .= "Here's a link to your purchased postage, just in case: https://" . ($_SETTINGS["test"] ? "test." : "") . "certifiedfromhome.com/pdf/" . $pdffile
. "\r\nPlease note that while you can print it more than once, mailing multiple copies is illegal.\r\n"; . "\r\nPlease note that while you can print it more than once, mailing multiple copies is illegal.\r\n";
$body .= "If you need any help, just reply to this email. Thanks again!"; $body .= "If you need any help, just reply to this email. Thanks again!";
$mail->setBody($body); $mail->setBody($body);
@ -216,7 +217,7 @@ try {
header("Content-Type: application/json"); header("Content-Type: application/json");
exit(json_encode([ exit(json_encode([
"status" => "OK", "status" => "OK",
"pdf" => "https://certifiedfromhome.com/pdf/" . $pdffile, "pdf" => "https://" . ($_SETTINGS["test"] ? "test." : "") . "certifiedfromhome.com/pdf/" . $pdffile,
"trackingcode" => $shipment->tracking_code "trackingcode" => $shipment->tracking_code
])); ]));
} else { } else {

View File

@ -3,6 +3,11 @@
require_once __DIR__ . "/vendor/autoload.php"; require_once __DIR__ . "/vendor/autoload.php";
require_once __DIR__ . "/settings.php"; require_once __DIR__ . "/settings.php";
\Sentry\init([
'dsn' => 'https://b1e259ce7e714dfeb49568c31ce99080@bugs.netsyms.net/10',
'environment' => ($_SETTINGS["test"] ? "test" : "production"),
]);
if ($_SETTINGS["debug"]) { if ($_SETTINGS["debug"]) {
error_reporting(E_ALL); error_reporting(E_ALL);
ini_set('display_errors', 'On'); ini_set('display_errors', 'On');
@ -18,7 +23,8 @@ foreach ($libs as $lib) {
require_once $lib; require_once $lib;
} }
\EasyPost\EasyPost::setApiKey($_SETTINGS["easypost_key"]); $easypostClient = new \EasyPost\EasyPostClient($_SETTINGS["easypost_key"]);
$stripeClient = new \Stripe\StripeClient($_SETTINGS["stripe_sk"]);
\Stripe\Stripe::setApiKey($_SETTINGS["stripe_sk"]); \Stripe\Stripe::setApiKey($_SETTINGS["stripe_sk"]);
header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Origin: *");