Handle membership submission and payment

master
Skylar Ittner 6 years ago
parent 00837a7bc1
commit c415e2f6ad

@ -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": [

68
composer.lock generated

@ -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": [],

Binary file not shown.

@ -6,4 +6,177 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
var_export($_POST);
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;
});

@ -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";
}
}
?>

@ -1,10 +0,0 @@
<?php
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
?>
<div class="container">
</div>

@ -6,7 +6,7 @@
*/
?>
<div class="container mt-4">
<form action="actions/submitmembership.php" method="post">
<form action="actions/submitmembership.php" method="post" id="membershipform">
<div class="card mb-4">
<div class="card-body">
@ -19,6 +19,18 @@
</div>
</div>
<?php
if (!empty($_GET['error'])) {
?>
<div class="card mb-4 bg-danger text-white">
<div class="card-body">
<?php echo htmlspecialchars($_GET['error']); ?>
</div>
</div>
<?php
}
?>
<div class="card mb-4">
<div class="card-header">
<h3><i class="fas fa-info fa-fw"></i> Basic Information</h3>
@ -72,7 +84,7 @@
"label" => "ZIP/Postal Code",
"icon" => "fas fa-mail-bulk",
"name" => "zip",
"maxlength" => 20,
"maxlength" => 10,
"width" => 3
],
[
@ -305,6 +317,19 @@
</div>
<div class="card mb-4">
<div class="card-header">
<h3><i class="fas fa-dollar-sign fa-fw"></i> Pay and Submit</h3>
</div>
<div class="card-body">
<label for="card-element">
Credit or debit card
</label>
<div id="card-element" class="form-control">
</div>
<div id="card-errors" class="alert alert-danger d-none"></div>
<input type="hidden" name="stripeToken" id="stripe-token" required />
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit Application</button>
</div>
@ -312,4 +337,8 @@
</form>
</div>
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe_pubkey = '<?php echo STRIPE_PUBKEY; ?>';
</script>
<script src="static/signup.js"></script>

@ -0,0 +1,23 @@
<?php
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
?>
<div class="container mt-4">
<div class="card mb-4 bg-success text-white">
<div class="card-body">
<div class="text-center">
<img class="img-fluid mb-4" style="max-height: 100px; min-width: 100px; filter: invert(100%);" src="static/hachelogo.svg" alt="HACHE: Helena Area Christian Home Educators"/>
<h1>Thank You!</h1>
<img class="img-fluid mb-4" style="max-height: 150px;" src="static/bigcheck.svg" alt="Checkmark"/>
<h4>Your membership has been submitted and paid for. We'll be in touch soon!</h4>
</div>
</div>
</div>
</div>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="256" height="256" version="1.1" viewBox="0 0 67.733 67.733" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -229.27)">
<g transform="translate(-2.1594 -2.3301)">
<circle cx="36.026" cy="265.46" r="25.346" fill="none" stroke="#fff" stroke-width="2.1167"/>
<g transform="matrix(.92594 0 0 .92594 15.724 23.148)" fill="#fff">
<g transform="translate(0 -10.583)" fill="#fff">
<rect transform="rotate(-45)" x="-186.61" y="215.33" width="50.291" height="2.286"/>
<rect transform="matrix(-.70711 -.70711 -.70711 .70711 0 0)" x="-217.62" y="184.32" width="18.288" height="2.286"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 698 B

@ -7,6 +7,44 @@
$("#add_child_row").click(function () {
$.get("parts/template_child_entry.php", {}, function (resp) {
$("#child_list").append(resp);
$("#child_list").append(resp);
});
});
// Create a Stripe client.
var stripe = Stripe(stripe_pubkey);
// Create an instance of Elements.
var elements = stripe.elements();
// Create an instance of the card Element.
var card = elements.create('card');
// Add an instance of the card Element into the `card-element` <div>.
card.mount('#card-element');
card.addEventListener('change', function (event) {
if (event.error) {
$("#card-errors").removeClass("d-none");
$("#card-errors").text(event.error.message);
} else {
$("#card-errors").addClass("d-none");
$("#card-errors").text("");
}
});
$("#membershipform").on("submit", function (event) {
event.preventDefault();
stripe.createToken(card).then(function (result) {
if (result.error) {
// Inform the customer that there was an error.
$("#card-errors").removeClass("d-none");
$("#card-errors").text(event.error.message);
} else {
$("#stripe-token").val(result.token.id);
console.log(result.token);
document.getElementById('membershipform').submit();
}
});
});

@ -20,6 +20,8 @@ define("DB_CHARSET", "utf8");
// Name of the app.
define("SITE_TITLE", "Membership Portal");
define("STRIPE_PUBKEY", "");
define("STRIPE_SECKEY", "");
// URL of the AccountHub API endpoint
define("PORTAL_API", "http://localhost/accounthub/api.php");

Loading…
Cancel
Save