<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[6709] sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments: WordCamp Payments: Add an "other" option on the Sponsorship Payment page</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="http://meta.trac.wordpress.org/changeset/6709">6709</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"http://meta.trac.wordpress.org/changeset/6709","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>coreymckrill</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2018-02-21 19:41:06 +0000 (Wed, 21 Feb 2018)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>WordCamp Payments: Add an "other" option on the Sponsorship Payment page

This allows a payment to be submitted that isn't associated with a particular
WordCamp or sponsor invoice.

Props coreymckrill</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentscsssponsorpaymentscss">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/css/sponsor-payments.css</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsincludessponsorpaymentstripephp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/includes/sponsor-payment-stripe.php</a></li>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsviewssponsorpaymentmainphp">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/views/sponsor-payment/main.php</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsjavascriptsponsorpaymentsjs">sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/javascript/sponsor-payments.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentscsssponsorpaymentscss"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/css/sponsor-payments.css</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/css/sponsor-payments.css        2018-02-21 19:30:44 UTC (rev 6708)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/css/sponsor-payments.css  2018-02-21 19:41:06 UTC (rev 6709)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,14 +1,15 @@
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.wcorg-sponsor-payment label,
-.wcorg-sponsor-payment .control {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.wcorg-sponsor-payment .control,
+.wcorg-sponsor-payment .control-header {
</ins><span class="cx" style="display: block; padding: 0 10px">         float: left;
</span><span class="cx" style="display: block; padding: 0 10px">        clear: both;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        width: 100%;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.wcorg-sponsor-payment label {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+.wcorg-sponsor-payment .control-header,
+#content.wcorg-sponsor-payment input[type="submit"] {
</ins><span class="cx" style="display: block; padding: 0 10px">         margin-top: 10px;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-.wcorg-sponsor-payment .clear {
-       display: block;
-       margin-bottom: 20px;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+#content.wcorg-sponsor-payment .other-fields input[name="description"] {
+       width: 100%;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsincludessponsorpaymentstripephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/includes/sponsor-payment-stripe.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/includes/sponsor-payment-stripe.php     2018-02-21 19:30:44 UTC (rev 6708)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/includes/sponsor-payment-stripe.php       2018-02-21 19:41:06 UTC (rev 6709)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -14,7 +14,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> const STEP_SELECT_INVOICE  = 1;
</span><span class="cx" style="display: block; padding: 0 10px"> const STEP_PAYMENT_DETAILS = 2;
</span><span class="cx" style="display: block; padding: 0 10px"> const STEP_PAYMENT_SUCCESS = 3;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-const CSS_VERSION          = 1;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+const JS_VERSION           = 1;
+const CSS_VERSION          = 2;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span><span class="cx" style="display: block; padding: 0 10px">  * Render the payment UI
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -32,18 +33,34 @@
</span><span class="cx" style="display: block; padding: 0 10px">        require_once( __DIR__ . '/wordcamp-budgets.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        $data = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'keys'       => $keys,
-               'step'       => STEP_SELECT_INVOICE,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'keys'                   => $keys,
+               'step'                   => STEP_SELECT_INVOICE,
</ins><span class="cx" style="display: block; padding: 0 10px">                 'wordcamp_query_options' => get_wordcamp_query_options(),
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                'currencies' => WordCamp_Budgets::get_currencies(),
-               'errors'     => array(),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         'currencies'             => WordCamp_Budgets::get_currencies(),
+               'errors'                 => array(),
</ins><span class="cx" style="display: block; padding: 0 10px">         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        if ( ! empty( $_POST['sponsor_payment_submit'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $submitted = filter_input( INPUT_POST, 'sponsor_payment_submit' );
+
+       if ( $submitted ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 _handle_post_data( $data ); // $data passed by ref.
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        wp_enqueue_style( 'wcb-sponsor-payments', plugins_url( 'css/sponsor-payments.css', __DIR__ ), array(), CSS_VERSION );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        wp_enqueue_script( 'wcb-sponsor-payments', plugins_url( 'javascript/sponsor-payments.js', __DIR__ ), array( 'jquery' ), JS_VERSION, true );
+
+       wp_localize_script(
+               'wcb-sponsor-payments',
+               'WordCampSponsorPayments',
+               array(
+                       'steps' => array(
+                               'select-invoice'  => STEP_SELECT_INVOICE,
+                               'payment-details' => STEP_PAYMENT_DETAILS,
+                               'payment-success' => STEP_PAYMENT_SUCCESS,
+                       ),
+               )
+       );
+
</ins><span class="cx" style="display: block; padding: 0 10px">         require_once( dirname( __DIR__ ) . '/views/sponsor-payment/main.php' );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -79,7 +96,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                'meta_query' => array(
</span><span class="cx" style="display: block; padding: 0 10px">                        array(
</span><span class="cx" style="display: block; padding: 0 10px">                                'key'     => 'Start Date (YYYY-mm-dd)',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'value'   => strtotime( '-3 months' ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'value'   => strtotime( '-2 years' ),
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'compare' => '>'
</span><span class="cx" style="display: block; padding: 0 10px">                        )
</span><span class="cx" style="display: block; padding: 0 10px">                )
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -96,66 +113,89 @@
</span><span class="cx" style="display: block; padding: 0 10px">  * @param array $data By-ref $data array that is passed to the view.
</span><span class="cx" style="display: block; padding: 0 10px">  */
</span><span class="cx" style="display: block; padding: 0 10px"> function _handle_post_data( &$data ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        $step = isset( $_POST['step'] ) ? absint( $_POST['step'] ) : STEP_SELECT_INVOICE;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $step = filter_input( INPUT_POST, 'step' );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        switch ( $_POST['step'] ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ switch ( $step ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                 // An invoice, event, currency and amount have been selected.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                case STEP_SELECT_INVOICE:
-                       if ( empty( $_POST['currency'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         default :
+               case STEP_SELECT_INVOICE :
+                       $payment_type = filter_input( INPUT_POST, 'payment_type' );
+                       $wordcamp_id  = filter_input( INPUT_POST, 'wordcamp_id', FILTER_VALIDATE_INT );
+                       $invoice_id   = filter_input( INPUT_POST, 'invoice_id', FILTER_VALIDATE_INT );
+                       $description  = filter_input( INPUT_POST, 'description' );
+                       $currency     = filter_input( INPUT_POST, 'currency' );
+                       $amount       = filter_input( INPUT_POST, 'amount', FILTER_VALIDATE_FLOAT );
+
+                       switch ( $payment_type ) {
+                               default :
+                               case 'invoice' :
+                                       if ( ! $wordcamp_id ) {
+                                               $data['errors'][] = 'Please select an event.';
+                                               return;
+                                       }
+
+                                       // Make sure the selected WordCamp is valid.
+                                       $valid_ids = wp_list_pluck( get_wordcamps( get_wordcamp_query_options() ), 'ID' );
+
+                                       if ( ! in_array( $wordcamp_id, $valid_ids ) ) {
+                                               $data['errors'][] = 'Please select a valid event.';
+                                               return;
+                                       }
+
+                                       $wordcamp_site_id = get_wordcamp_site_id( get_post( $wordcamp_id ) );
+
+                                       if ( empty( $wordcamp_site_id ) ) {
+                                               $data['errors'][] = 'Could not find a site for this WordCamp.';
+                                               return;
+                                       }
+
+                                       if ( ! $invoice_id ) {
+                                               $data['errors'][] = 'Please provide a valid invoice ID.';
+                                               return;
+                                       }
+                                       break;
+
+                               case 'other' :
+                                       $description = substr( sanitize_text_field( $description ), 0, 100 );
+
+                                       if ( ! $description ) {
+                                               $data['errors'][] = 'Please describe the purpose of the payment.';
+                                               return;
+                                       }
+                                       break;
+                       }
+
+                       if ( ! $currency ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $data['errors'][] = 'Please select a currency.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $currency = $_POST['currency'];
</del><span class="cx" style="display: block; padding: 0 10px">                         if ( ! array_key_exists( $currency, $data['currencies'] ) || false !== strpos( $currency, 'null' ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $data['errors'][] = 'Invalid currency.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( empty( $_POST['amount'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $amount = round( $amount, 2 );
+
+                       if ( ! $amount ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $data['errors'][] = 'Please enter a payment amount.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $amount = round( floatval( $_POST['amount'] ), 2 );
</del><span class="cx" style="display: block; padding: 0 10px">                         if ( $amount < 1.00 ) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $data['errors'][] = 'Amount can not be less than 1.00.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if ( empty( $_POST['wordcamp_id'] ) ) {
-                               $data['errors'][] = 'Please select an event.';
-                               return;
-                       }
-
-                       // Make sure the selected WordCamp is valid.
-                       $wordcamp_id = absint( $_POST['wordcamp_id'] );
-                       $valid_ids   = wp_list_pluck( get_wordcamps( get_wordcamp_query_options() ), 'ID' );
-
-                       if ( ! in_array( $wordcamp_id, $valid_ids ) ) {
-                               $data['errors'][] = 'Please select a valid event.';
-                               return;
-                       }
-
-                       if ( empty( $_POST['invoice_id'] ) ) {
-                               $data['errors'][] = 'Please provide a valid invoice ID.';
-                               return;
-                       }
-
-                       $invoice_id       = absint( $_POST['invoice_id'] );
-                       $wordcamp_site_id = get_wordcamp_site_id( get_post( $wordcamp_id ) );
-                       if ( empty( $wordcamp_site_id ) ) {
-                               $data['errors'][] = 'Could not find a site for this WordCamp.';
-                               return;
-                       }
-
</del><span class="cx" style="display: block; padding: 0 10px">                         // Next step is to collect the card details via Stripe.
</span><span class="cx" style="display: block; padding: 0 10px">                        $data['step']    = STEP_PAYMENT_DETAILS;
</span><span class="cx" style="display: block; padding: 0 10px">                        $data['payment'] = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'currency'    => $currency,
-                               'amount'      => $amount,
-                               'wordcamp_id' => $wordcamp_id,
-                               'invoice_id'  => $invoice_id,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'payment_type' => $payment_type,
+                               'wordcamp_id'  => $wordcamp_id,
+                               'invoice_id'   => $invoice_id,
+                               'description'  => $description,
+                               'currency'     => $currency,
+                               'amount'       => $amount,
</ins><span class="cx" style="display: block; padding: 0 10px">                         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        // Passed through to the charge step.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -167,42 +207,69 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        break;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // The card details have been entered and Stripe has submitted our form.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                case STEP_PAYMENT_DETAILS:
-                       if ( empty( $_POST['stripeToken'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         case STEP_PAYMENT_DETAILS :
+                       $stripe_token           = filter_input( INPUT_POST, 'stripeToken' );
+                       $payment_data_json      = filter_input( INPUT_POST, 'payment_data_json' );
+                       $payment_data_signature = filter_input( INPUT_POST, 'payment_data_signature' );
+
+                       if ( ! $stripe_token ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $data['errors'][] = 'Stripe token not found.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        if ( ! $payment_data_json || ! $payment_data_signature ) {
+                               $data['errors'][] = 'Payment data is missing.';
+                               return;
+                       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         // Make sure our data hasn't been altered.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $payment_data_str = wp_unslash( $_POST['payment_data_json'] );
-                       $payment_data     = json_decode( $payment_data_str, true );
-                       if ( ! hash_equals( hash_hmac( 'sha256', $payment_data_str, $data['keys']['hmac_key'] ), $_POST['payment_data_signature'] ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $payment_data_str = wp_unslash( $payment_data_json );
+
+                       if ( ! hash_equals( hash_hmac( 'sha256', $payment_data_str, $data['keys']['hmac_key'] ), $payment_data_signature ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $data['errors'][] = 'Could not verify payload signature.';
</span><span class="cx" style="display: block; padding: 0 10px">                                return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $wordcamp_obj      = get_post( $payment_data['wordcamp_id'] );
-                       $wordcamp_site_id  = get_wordcamp_site_id( $wordcamp_obj );
-                       $wordcamp_site_url = set_url_scheme( esc_url_raw( get_blog_option( $wordcamp_site_id, 'home', '' ) ), 'https' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $payment_data = json_decode( $payment_data_str, true );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        switch ( $payment_data['payment_type'] ) {
+                               case 'invoice' :
+                                       $wordcamp_obj     = get_post( $payment_data['wordcamp_id'] );
+                                       $wordcamp_site_id = get_wordcamp_site_id( $wordcamp_obj );
+
+                                       $description = sprintf( 'WordCamp Sponsorship: %s', get_wordcamp_name( $wordcamp_site_id ) );
+                                       $metadata    = array(
+                                               'invoice_id'       => $payment_data['invoice_id'],
+                                               'wordcamp_id'      => $payment_data['wordcamp_id'],
+                                               'wordcamp_site_id' => $wordcamp_site_id,
+                                               'wordcamp_url'     => set_url_scheme( esc_url_raw( get_blog_option( $wordcamp_site_id, 'home', '' ) ), 'https' ),
+                                       );
+                                       break;
+
+                               case 'other' :
+                                       $description = 'Other Payment';
+                                       $metadata    = array(
+                                               'description' => $payment_data['description'],
+                                       );
+                                       break;
+                       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         $body = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'amount'      => round( $payment_data['amount'], 2 ) * 100,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'amount'      => round( $payment_data['amount'], 2 ) * 100, // TODO handle zero-decimal currencies.
</ins><span class="cx" style="display: block; padding: 0 10px">                                 'currency'    => $payment_data['currency'],
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                'source'      => $_POST['stripeToken'],
-                               'description' => 'WordCamp Sponsorship: ' . $wordcamp_obj->post_title,
-                               'metadata'    => array(
-                                       'invoice_id'       => $payment_data['invoice_id'],
-                                       'wordcamp_id'      => $payment_data['wordcamp_id'],
-                                       'wordcamp_site_id' => $wordcamp_site_id,
-                                       'wordcamp_url'     => $wordcamp_site_url,
-                               ),
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         'source'      => $stripe_token,
+                               'description' => $description,
+                               'metadata'    => $metadata,
</ins><span class="cx" style="display: block; padding: 0 10px">                         );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        try {
</span><span class="cx" style="display: block; padding: 0 10px">                                $stripe = new Stripe_Client( $data['keys']['secret'] );
</span><span class="cx" style="display: block; padding: 0 10px">                                $charge = $stripe->charge( $body );
</span><span class="cx" style="display: block; padding: 0 10px">                        } catch ( Exception $exception ) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $data['errors'][] = "An error occurred, please try another card. If that doesn't work, please contact ". EMAIL_CENTRAL_SUPPORT .".";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $data['errors'][] = sprintf(
+                                       "An error occurred, please try another card. If that doesn't work, please contact %s.",
+                                       EMAIL_CENTRAL_SUPPORT
+                               );
</ins><span class="cx" style="display: block; padding: 0 10px">                                 return;
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsjavascriptsponsorpaymentsjs"></a>
<div class="addfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Added: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/javascript/sponsor-payments.js</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/javascript/sponsor-payments.js                          (rev 0)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/javascript/sponsor-payments.js    2018-02-21 19:41:06 UTC (rev 6709)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -0,0 +1,61 @@
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+( function( window, $ ) {
+
+       'use strict';
+
+       var preLoadedData = window.WordCampSponsorPayments || {},
+               app;
+
+       app = $.extend( preLoadedData, {
+               /**
+                * Run on page load.
+                */
+               init: function() {
+                       $.map( this.steps, parseInt );
+
+                       var $form = $('.payment-form'),
+                               currentStep;
+
+                       if ( $form.length ) {
+                               currentStep = parseInt( $form.data('step') );
+                       }
+
+                       switch ( currentStep ) {
+                               case this.steps['select-invoice'] :
+                                       this.initSelectInvoice();
+                                       break;
+                       }
+               },
+
+               /**
+                * Run if the page is on the Select Invoice step.
+                */
+               initSelectInvoice: function() {
+                       var $form = $('.payment-form'),
+                               $controlType = $form.find('input[name=payment_type]'),
+                               $invoiceFields = $form.find('.invoice-fields'),
+                               $otherFields = $form.find('.other-fields');
+
+                       $controlType.change( function() {
+                               if ( $( this ).is(':checked') ){
+                                       switch ( this.value ) {
+                                               case 'invoice' :
+                                                       $invoiceFields.show();
+                                                       $otherFields.hide();
+                                                       break;
+
+                                               case 'other' :
+                                                       $otherFields.show();
+                                                       $invoiceFields.hide();
+                                                       break;
+                                       }
+                               }
+                       } );
+
+                       $controlType.trigger( 'change' );
+               }
+       } );
+
+       app.init();
+
+} )( window, jQuery );
</ins></span></pre></div>
<a id="sitestrunkwordcamporgpublic_htmlwpcontentpluginswordcamppaymentsviewssponsorpaymentmainphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/views/sponsor-payment/main.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/views/sponsor-payment/main.php  2018-02-21 19:30:44 UTC (rev 6708)
+++ sites/trunk/wordcamp.org/public_html/wp-content/plugins/wordcamp-payments/views/sponsor-payment/main.php    2018-02-21 19:41:06 UTC (rev 6709)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1,6 +1,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> <?php
</span><span class="cx" style="display: block; padding: 0 10px"> namespace WordCamp\Budgets\Sponsor_Payment_Stripe;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+/** @var array $data */
+
</ins><span class="cx" style="display: block; padding: 0 10px"> get_header();
</span><span class="cx" style="display: block; padding: 0 10px"> ?>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -19,24 +21,43 @@
</span><span class="cx" style="display: block; padding: 0 10px">                <?php endif; ?>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                <?php if ( $data['step'] == STEP_SELECT_INVOICE ) : ?>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        <p class="payment-instructions">
+                               <?php esc_html_e( 'Use this form to pay your WordCamp sponsorship fee to WordPress Community Support, PBC. If you did not receive an invoice ID yet, please get in touch with the event\'s Sponsorships Coordinator for more information.', 'wordcamporg' ); ?>
+                       </p>
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <p><?php esc_html_e( 'Use this form to pay your WordCamp sponsorship fee to WordPress Community Support, PBC. If you did not receive an invoice ID yet, please get in touch with the event\'s Sponsorships Coordinator for more information.', 'wordcamporg' ); ?></p>
-
-                       <form method="POST">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <form method="POST" class="payment-form" data-step="<?php echo STEP_SELECT_INVOICE; ?>">
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <input type="hidden" name="step" value="<?php echo STEP_SELECT_INVOICE; ?>" />
</span><span class="cx" style="display: block; padding: 0 10px">                                <input type="hidden" name="sponsor_payment_submit" value="1" />
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <label><?php esc_html_e( 'Event', 'wordcamporg' ); ?></label>
</del><span class="cx" style="display: block; padding: 0 10px">                                 <div class="control">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        <?php echo get_wordcamp_dropdown( 'wordcamp_id', $data['wordcamp_query_options'] ); ?>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 <input type="radio" id="payment_type_invoice" name="payment_type" value="invoice" checked> <label for="payment_type_invoice"><?php esc_html_e( 'Invoice payment', 'wordcamporg' ); ?></label>
+                                       <input type="radio" id="payment_type_other" name="payment_type" value="other"> <label for="payment_type_other"><?php esc_html_e( 'Other payment', 'wordcamporg' ); ?></label>
</ins><span class="cx" style="display: block; padding: 0 10px">                                 </div>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <label><?php esc_html_e( 'Invoice ID', 'wordcamporg' ); ?></label>
-                               <div class="control">
-                                       <input type="text" name="invoice_id" />
-                               </div>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <div class="clear"></div>
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <label><?php esc_html_e( 'Currency', 'wordcamporg' ); ?></label>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <fieldset class="invoice-fields">
+                                       <label class="control-header"><?php esc_html_e( 'Event', 'wordcamporg' ); ?></label>
+                                       <div class="control">
+                                               <?php echo get_wordcamp_dropdown( 'wordcamp_id', $data['wordcamp_query_options'] ); ?>
+                                       </div>
+
+                                       <label class="control-header"><?php esc_html_e( 'Invoice ID', 'wordcamporg' ); ?></label>
+                                       <div class="control">
+                                               <input type="text" name="invoice_id" />
+                                       </div>
+                               </fieldset>
+
+                               <fieldset class="other-fields">
+                                       <label class="control-header"><?php esc_html_e( 'Description (100 character limit)', 'wordcamporg' ); ?></label>
+                                       <div class="control">
+                                               <input type="text" name="description" maxlength="100" value="" />
+                                       </div>
+                               </fieldset>
+
+                               <div class="clear"></div>
+
+                               <label class="control-header"><?php esc_html_e( 'Currency', 'wordcamporg' ); ?></label>
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <div class="control">
</span><span class="cx" style="display: block; padding: 0 10px">                                        <select name="currency">
</span><span class="cx" style="display: block; padding: 0 10px">                                                <option value="" disabled selected><?php esc_html_e( 'Select a Currency', 'wordcamporg' ); ?></option>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -50,7 +71,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        </select>
</span><span class="cx" style="display: block; padding: 0 10px">                                </div>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                <label><?php esc_html_e( 'Amount', 'wordcamporg' ); ?></label>
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         <label class="control-header"><?php esc_html_e( 'Amount', 'wordcamporg' ); ?></label>
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <div class="control">
</span><span class="cx" style="display: block; padding: 0 10px">                                        <input type="text" name="amount" /><br />
</span><span class="cx" style="display: block; padding: 0 10px">                     <em><?php esc_html_e( 'An additional 2.9% to cover processing fees on credit card payments is highly appreciated but not required.', 'wordcamporg' ); ?></em>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -66,15 +87,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        <p><?php esc_html_e( 'Please review the details below and hit "Make a Payment" when you\'re ready.', 'wordcamporg' ); ?></p>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        <table>
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                <?php if ( 'invoice' === $data['payment']['payment_type'] ) : ?>
+                                       <tr>
+                                               <td><?php esc_html_e( 'Event', 'wordcamporg' ); ?></td>
+                                               <td><?php echo esc_html( get_wordcamp_name( get_wordcamp_site_id( $data['payment']['wordcamp_obj'] ) ) ); ?></td>
+                                       </tr>
+                                       <tr>
+                                               <td><?php esc_html_e( 'Invoice', 'wordcamporg' ); ?></td>
+                                               <td><?php echo esc_html( $data['payment']['invoice_id'] ); ?></td>
+                                       </tr>
+                               <?php elseif ( 'other' === $data['payment']['payment_type'] ) : ?>
+                                       <tr>
+                                               <td><?php esc_html_e( 'Description', 'wordcamporg' ); ?></td>
+                                               <td><?php echo esc_html( $data['payment']['description'] ); ?></td>
+                                       </tr>
+                               <?php endif; ?>
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <tr>
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        <td><?php esc_html_e( 'Invoice', 'wordcamporg' ); ?></td>
-                                       <td><?php echo esc_html( $data['payment']['invoice_id'] ); ?></td>
-                               </tr>
-                               <tr>
-                                       <td><?php esc_html_e( 'Event', 'wordcamporg' ); ?></td>
-                                       <td><?php echo esc_html( $data['payment']['wordcamp_obj']->post_title ); ?></td>
-                               </tr>
-                               <tr>
</del><span class="cx" style="display: block; padding: 0 10px">                                         <td><?php esc_html_e( 'Currency', 'wordcamporg' ); ?></td>
</span><span class="cx" style="display: block; padding: 0 10px">                                        <td><?php echo esc_html( $data['payment']['currency'] ); ?></td>
</span><span class="cx" style="display: block; padding: 0 10px">                                </tr>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -84,7 +112,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                </tr>
</span><span class="cx" style="display: block; padding: 0 10px">                        </table>
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        <form method="POST">
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 <form method="POST" class="payment-form" data-step="<?php echo STEP_PAYMENT_DETAILS; ?>">
</ins><span class="cx" style="display: block; padding: 0 10px">                                 <input type="hidden" name="step" value="<?php echo STEP_PAYMENT_DETAILS; ?>" />
</span><span class="cx" style="display: block; padding: 0 10px">                                <input type="hidden" name="sponsor_payment_submit" value="1" />
</span><span class="cx" style="display: block; padding: 0 10px">                                <input type="hidden" name="payment_data_json" value="<?php echo esc_attr( $data['payment_data_json'] ); ?>" />
</span></span></pre>
</div>
</div>

</body>
</html>