diff --git a/composer.json b/composer.json index 5909527..ea90c45 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "type": "project", "require": { "catfan/medoo": "^1.5", - "guzzlehttp/guzzle": "^6.2" + "guzzlehttp/guzzle": "^6.2", + "stripe/stripe-php": "^6.24" }, "license": "MPL-2.0", "authors": [ diff --git a/composer.lock b/composer.lock index 8d36028..5535e42 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "5c7439c6e041764f2f6b0270a95ab3ae", - "content-hash": "e4e700119f47d2f68b0ed82abaf8c5c6", + "content-hash": "87c8c709e248bfe62291e8208765fd01", "packages": [ { "name": "catfan/medoo", @@ -64,7 +63,7 @@ "sql", "sqlite" ], - "time": "2018-06-14 18:59:08" + "time": "2018-06-14T18:59:08+00:00" }, { "name": "guzzlehttp/guzzle", @@ -129,7 +128,7 @@ "rest", "web service" ], - "time": "2018-04-22 15:46:56" + "time": "2018-04-22T15:46:56+00:00" }, { "name": "guzzlehttp/promises", @@ -180,7 +179,7 @@ "keywords": [ "promise" ], - "time": "2016-12-20 10:07:11" + "time": "2016-12-20T10:07:11+00:00" }, { "name": "guzzlehttp/psr7", @@ -245,7 +244,7 @@ "uri", "url" ], - "time": "2017-03-20 17:10:46" + "time": "2017-03-20T17:10:46+00:00" }, { "name": "psr/http-message", @@ -295,7 +294,62 @@ "request", "response" ], - "time": "2016-08-06 14:39:51" + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "stripe/stripe-php", + "version": "v6.24.0", + "source": { + "type": "git", + "url": "https://github.com/stripe/stripe-php.git", + "reference": "e608b6538b45d233db66838c389c6548c1152a27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stripe/stripe-php/zipball/e608b6538b45d233db66838c389c6548c1152a27", + "reference": "e608b6538b45d233db66838c389c6548c1152a27", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "1.*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Stripe\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stripe and contributors", + "homepage": "https://github.com/stripe/stripe-php/contributors" + } + ], + "description": "Stripe PHP Library", + "homepage": "https://stripe.com/", + "keywords": [ + "api", + "payment processing", + "stripe" + ], + "time": "2018-11-28T16:32:29+00:00" } ], "packages-dev": [], diff --git a/database.mwb b/database.mwb index df06dfb..a54c587 100644 Binary files a/database.mwb and b/database.mwb differ diff --git a/public/actions/submitmembership.php b/public/actions/submitmembership.php index 9a80716..24ffe1f 100644 --- a/public/actions/submitmembership.php +++ b/public/actions/submitmembership.php @@ -6,4 +6,177 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -var_export($_POST); \ No newline at end of file +require_once __DIR__ . "/../../lib/requiredpublic.php"; + +function errorBack(string $errormsg) { + header("Location: ../?error=" . htmlentities($errormsg)); + die($errormsg); +} + +if (empty($_POST['agree_terms'])) { + errorBack("You must agree to HACHE's policy."); +} + +$database->action(function($database) { + $lastname = $_POST['familyname']; + $father = $_POST['fathername']; + $mother = $_POST['mothername']; + + if (empty($lastname)) { + errorBack("Enter a last name."); + } + if (empty($father)) { + errorBack("Enter a father name."); + } + if (empty($mother)) { + errorBack("Enter a mother name."); + } + + $phone = $_POST['phone']; + $phone = preg_replace("/[^0-9]/", "", $phone); + if (strlen($phone) == 11) { + $phone = preg_replace("/^1/", "", $phone); + } + if (strlen($phone) != 10) { + errorBack("Enter a valid 10-digit phone number."); + } + + $email = $_POST['email']; + if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { + errorBack("The email address looks wrong."); + } + + $address = $_POST['streetaddress']; + $city = $_POST['city']; + $state = strtoupper($_POST['state']); + $zip = $_POST['zip']; + if (empty($address)) { + errorBack("Enter a street address."); + } + if (empty($city)) { + errorBack("Enter a city."); + } + if (!preg_match("/^[A-Z]{2}$/", $state)) { + errorBack("Enter a valid two-character state (MT, WY, ID, etc)."); + } + if (!preg_match("/^[0-9]{5}(-?[0-9]{4})?$/", $zip)) { + errorBack("Enter a valid five or nine digit US ZIP code."); + } + + $newsletter = $_POST['newsletter_method']; + $membership_cost = 2500; + if (empty($newsletter)) { + errorBack("Select a newsletter preference."); + } + switch ($newsletter) { + case 1: // Email only + $membership_cost = 2500; + break; + case 2: // Print only + $membership_cost = 3500; + break; + case 3: // Email and print + $membership_cost = 3500; + break; + default: + errorBack("Select a valid newsletter preference."); + } + + $photopermission = $_POST['photo_permission']; + if (!empty($photopermission) && $photopermission == "1") { + $photopermission = true; + } else { + $photopermission = false; + } + + $database->insert("families", [ + "familyname" => $lastname, + "father_name" => $father, + "mother_name" => $mother, + "phone" => $phone, + "email" => $email, + "newsletter_method" => $newsletter, + "address" => $address, + "city" => $city, + "state" => $state, + "zip" => $zip, + "photo_permission" => $photopermission + ]); + + $familyid = $database->id(); + + $children = $_POST['child']; + + foreach ($children['ids'] as $cid) { + if (empty($children['name'][$cid])) { + continue; + } + + if (!preg_match("/^([1-9]|1[012])$/", $children['month'][$cid])) { + errorBack("Invalid birth month chosen for " . htmlentities($children['name'][$cid]) . "."); + } + + if (!is_numeric($children['year'][$cid])) { + errorBack("Invalid birth year chosen for " . htmlentities($children['name'][$cid]) . "."); + } + $children['year'][$cid] = $children['year'][$cid] * 1; + if ($children['year'][$cid] < 1980 || $children['year'][$cid] > date("Y")) { + errorBack("Invalid birth year chosen for " . htmlentities($children['name'][$cid]) . "."); + } + + $database->insert("people", [ + "familyid" => $familyid, + "name" => $children['name'][$cid], + "birthday" => $children['year'][$cid] . "-" . $children['month'][$cid] . "-00", + "graduated" => empty($children['graduate'][$cid]) ? 0 : 1 + ]); + } + + $interests = []; + foreach ($_POST['events'] as $evt) { + if ($database->has("events", ['eventid' => $evt])) { + $interests[] = ["familyid" => $familyid, "eventid" => $evt]; + } + } + $database->insert("interests", $interests); + + + try { + \Stripe\Stripe::setApiKey(STRIPE_SECKEY); + + $charge = \Stripe\Charge::create([ + 'amount' => $membership_cost, + 'currency' => 'usd', + 'description' => 'HACHE Membership', + 'source' => $_POST['stripeToken'], + 'statement_descriptor' => 'HACHE Membership 1yr', + ]); + + } catch (\Stripe\Error\Card $e) { + $body = $e->getJsonBody(); + $err = $body['error']; + errorBack("We couldn't process your card because it was declined. Your card issuer or bank sent us this message: " . $err["message"] . " That's all we know."); + } catch (\Stripe\Error\RateLimit $e) { + errorBack("We couldn't process your card because things are happening too fast. Please try again in a minute. (Error code: STRIPE_RATELIMIT)"); + } catch (\Stripe\Error\InvalidRequest $e) { + errorBack("We couldn't process your card because of a technical issue. Please try again later. (Error code: STRIPE_INVREQ)"); + } catch (\Stripe\Error\Authentication $e) { + errorBack("We can't connect to the card processor. Please try again later. (Error code: STRIPE_AUTH)"); + } catch (\Stripe\Error\ApiConnection $e) { + errorBack("We can't connect to the card processor. Please try again later. (Error code: STRIPE_NOAPI)"); + } catch (\Stripe\Error\Base $e) { + errorBack("An unknown payment error occurred. Please try again later."); + } catch (Exception $e) { + errorBack("An unknown error occurred. Please try again later."); + } + + $database->insert("payments", [ + "familyid" => $familyid, + "amount" => ($membership_cost / 100.0), + "paid" => 1, + "date" => date("Y-m-d H:i:s") + ]); + + header("Location: ../?page=thanks"); + return true; +}); diff --git a/public/index.php b/public/index.php index 7adba6f..3250e6a 100644 --- a/public/index.php +++ b/public/index.php @@ -10,8 +10,8 @@ require_once __DIR__ . "/../lib/requiredpublic.php"; $page = "signup.php"; if (!empty($_GET['page'])) { switch ($_GET['page']) { - case "pay": - $page = "pay.php"; + case "thanks": + $page = "thanks.php"; } } ?> diff --git a/public/parts/pay.php b/public/parts/pay.php deleted file mode 100644 index a9f1bc9..0000000 --- a/public/parts/pay.php +++ /dev/null @@ -1,10 +0,0 @@ - -