Answers.Body: <p>Currently, you will have to either use a plugin, or dump all your content into a notes field given by Charge (this would require JS coding). There are new features coming up in 2.0, but you would need to talk to <a href="http://squarebit.co.uk/" rel="nofollow">Joel over at Square Bit</a> for any details. If this is a crucial feature, you can hire a Craft developer over at <a href="http://straightupcraft.com/professionals" rel="nofollow">Straight Up Craft</a>.</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-08T10:48:55.683Z
Answers.LastActivityDate: 2014-10-08T10:48:55.683Z
Answers.UserDisplayName: Bryan Redeagle
Answers.Body: <p>We did something similar with Charge when we were accepting payments for a <a href="http://buildwithcraft.com/training">Craft Virtual Training</a> course. It does involve writing a plugin, but thankfully all of the heavy lifting for saving entries and charging credit cards is handled by the services provided by Craft and Charge, so the only thing the plugin has to worry about is collecting post data and passing it to some APIs.</p>
  
  <p>Start off by creating a primary plugin class (see <a href="http://buildwithcraft.com/docs/plugins/setting-things-up">Setting Things Up</a> in the Craft plugin docs), and then giving your plugin a <a href="http://buildwithcraft.com/docs/plugins/controllers">controller</a> with the following code:</p>
  
  <pre class="lang-php prettyprint-override"><code>&lt;?php
  namespace Craft;
  
  class FooController extends BaseController
  {
      public $allowAnonymous = array('actionCreateBooking');
  
      public function actionCreateBooking()
      {
          // Require this to be a POST request
          $this-&gt;requirePostRequest();
  
          // Require that the user is logged in
          craft()-&gt;userSession-&gt;requireLogin();
  
          // Get the user
          $user = craft()-&gt;userSession-&gt;getUser();
  
          // Do any custom validation here
          // ...
  
          // Charge the card
          $charge = new ChargeModel();
  
          $charge-&gt;cardToken     = craft()-&gt;request-&gt;getRequiredPost('cardToken');
          $charge-&gt;cardLast4     = craft()-&gt;request-&gt;getPost('cardLast4');
          $charge-&gt;cardType      = craft()-&gt;request-&gt;getPost('cardType');
          $charge-&gt;cardName      = craft()-&gt;request-&gt;getPost('cardName');
          $charge-&gt;cardExpMonth  = craft()-&gt;request-&gt;getPost('cardExpMonth');
          $charge-&gt;cardExpYear   = craft()-&gt;request-&gt;getPost('cardExpYear');
  
          $charge-&gt;customerName  = craft()-&gt;request-&gt;getPost('customerName');
          $charge-&gt;customerEmail = craft()-&gt;request-&gt;getPost('customerEmail');
  
          $charge-&gt;planAmount    = 10000; // In cents
  
          if ($charge-&gt;validate() &amp;&amp; craft()-&gt;charge-&gt;handlePayment($charge))
          {
              // Save the booking entry
              $entry = new EntryModel();
              $entry-&gt;sectionId = craft()-&gt;request-&gt;getPost('sectionId');
              $entry-&gt;typeId    = craft()-&gt;request-&gt;getPost('typeId'); // Not necessary if there's only one entry type
              $entry-&gt;authorId  = $user-&gt;id;
              $entry-&gt;enabled   = true;
  
              $entry-&gt;getContent()-&gt;title = 'New Booking: '.$user-&gt;username;
              $entry-&gt;getContent()-&gt;chargeId = $charge-&gt;id; // Custom number field
              $entry-&gt;getContent()-&gt;someOtherCustomField = 'xyz';
  
              craft()-&gt;entries-&gt;saveEntry($entry);
  
              // Redirect the request based on the 'redirect' param
              craft()-&gt;userSession-&gt;setNotice('Booking saved.');
              $this-&gt;redirectToPostedUrl();
          }
          else
          {
              craft()-&gt;userSession-&gt;setError('Couldn’t charge the card.');
  
              // Send the charge model to the template
              craft()-&gt;urlManager-&gt;setRouteVariables(array(
                  'charge' =&gt; $charge
              ));
          }
      }
  }
  </code></pre>
  
  <p>You might want to hard-code the sectionId and typeId rather than leaving it up to the POST data, and there might be other slight changes you want to make, but that’s the gist.</p>
  
  <p>With the plugin in place, you would just need to create a form that captures all of the info the controller is looking for, and posts it to the <code>foo/createBooking</code> action:</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;form method="post" accept-charset="UTF-8"&gt;
      {{ getCsrfInput() }}
      &lt;input type="hidden" name="action" value="foo/createBooking"&gt;
  
      &lt;!-- ... --&gt;
  &lt;/form&gt;
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-09T10:24:07.703Z
Answers.Text: Thank you so much Brandon - saved me time and money posting that. And I've got a better idea of how the plugin stuff works together after seeing a live example. I did hardcode the section ID after all, and I see how the custom fields work. Brilliant!
Answers.UserDisplayName: darylknight
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-09T13:40:58.460Z
Answers.Text: Exactly what Brandon said. I've implemented that same solution a number of times for projects (and while it's semi-obvious when you know what's going on it's not always clear this approach can work for basically any similar setup).
Answers.UserDisplayName: Joel Bradbury
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-30T14:17:08.080Z
Answers.Text: Hi Joel/Brandon - just revisiting this now and I've realised that the {hash} from the payment form (charge/success/{hash}) doesn't work when using the plugin as an action instead of charge/charge - it sends the user to /charge/success/%7Bhash%7D. Is there a way to get the plugin to pull in the hash from Charge?
Answers.UserDisplayName: darylknight
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-30T16:40:02.003Z
Answers.Text: @DarylKnight If you're running your own controller infront of the charge payment you can adjust the redirect directly after the craft()->charge->handlePayment returns. I couldn't say exactly why the {hash} isn't automatically parsing in your case, that specific variable replacement is inherited from Craft's internal request controllers not something Charge is doing specially.
Answers.UserDisplayName: Joel Bradbury
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-30T16:53:59.180Z
Answers.Text: No problem, thanks for getting back to me!
Answers.UserDisplayName: darylknight
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2015-04-29T12:20:26.450Z
Answers.Text: Just to update this comment above about {hash} not being properly parsed out, it's just a case of making sure you pass the object to the redirectToPostedUrl() method, so, in this case that'd be : $this->redirectToPostedUrl($charge)
Answers.UserDisplayName: Joel Bradbury
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-10-08T15:36:31.000Z
Answers.LastActivityDate: 2014-10-08T18:38:39.317Z
Answers.LastEditDate: 2014-10-08T18:38:39.317Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>First off, I appreciate this is open ended and SE isn't the best place for it. For a lack of a better place to ask though, here we are:</p>
  
  <p>I've just built a system for a client where users could sign up an book places on events. None of the bookings on this system require payment, so it's just a case of submitting a form which creates an entry in a channel called "bookings" using:</p>
  
  <pre><code>action=saveEntry
  </code></pre>
  
  <p>I now have a client who needs to take bookings for events which require payment, and to list those bookings in a front end page. I'm trying to use <a href="http://squarebit.co.uk/plugins/charge">Charge</a> for payments (only because it seems easy to use, and my client doesn't want to pay monthly for something), which requires the form action:</p>
  
  <pre><code>action=charge/charge
  </code></pre>
  
  <p>The issue I have is that I want to submit a single form which takes a payment and creates a booking (action=saveEntry) <strong>without writing a plugin</strong>. I'm not a backend developer, I don't know how to write plugins (despite trying). None of the eCommerce addons available for Craft are out of beta yet.</p>
  
  <p>Is there any way to take a payment and create a booking using template code?</p>
  
Tags: <plugin-development><events><booking>
Title: Booking paid-for events: How?
ThreadText: # Booking paid-for events: How?
  
  (Asked by: username_0 on 2014-10-08)
  
  First off, I appreciate this is open ended and SE isn't the best place for it. For a lack of a better place to ask though, here we are:
  
  I've just built a system for a client where users could sign up an book places on events. None of the bookings on this system require payment, so it's just a case of submitting a form which creates an entry in a channel called "bookings" using:
  
  ```
  action=saveEntry
  
  ```
  
  I now have a client who needs to take bookings for events which require payment, and to list those bookings in a front end page. I'm trying to use [Charge](http://squarebit.co.uk/plugins/charge) for payments (only because it seems easy to use, and my client doesn't want to pay monthly for something), which requires the form action:
  
  ```
  action=charge/charge
  
  ```
  
  The issue I have is that I want to submit a single form which takes a payment and creates a booking (action=saveEntry) **without writing a plugin**. I'm not a backend developer, I don't know how to write plugins (despite trying). None of the eCommerce addons available for Craft are out of beta yet.
  
  Is there any way to take a payment and create a booking using template code?
  
  **Tags:** plugin-development, events, booking
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2014-10-08. Score: 11 | Accepted answer
  
  We did something similar with Charge when we were accepting payments for a [Craft Virtual Training](http://buildwithcraft.com/training) course. It does involve writing a plugin, but thankfully all of the heavy lifting for saving entries and charging credit cards is handled by the services provided by Craft and Charge, so the only thing the plugin has to worry about is collecting post data and passing it to some APIs.
  
  Start off by creating a primary plugin class (see [Setting Things Up](http://buildwithcraft.com/docs/plugins/setting-things-up) in the Craft plugin docs), and then giving your plugin a [controller](http://buildwithcraft.com/docs/plugins/controllers) with the following code:
  
  ```php
  <?php
  namespace Craft;
  
  class FooController extends BaseController
  {
      public $allowAnonymous = array('actionCreateBooking');
  
      public function actionCreateBooking()
      {
          // Require this to be a POST request
          $this->requirePostRequest();
  
          // Require that the user is logged in
          craft()->userSession->requireLogin();
  
          // Get the user
          $user = craft()->userSession->getUser();
  
          // Do any custom validation here
          // ...
  
          // Charge the card
          $charge = new ChargeModel();
  
          $charge->cardToken     = craft()->request->getRequiredPost('cardToken');
          $charge->cardLast4     = craft()->request->getPost('cardLast4');
          $charge->cardType      = craft()->request->getPost('cardType');
          $charge->cardName      = craft()->request->getPost('cardName');
          $charge->cardExpMonth  = craft()->request->getPost('cardExpMonth');
          $charge->cardExpYear   = craft()->request->getPost('cardExpYear');
  
          $charge->customerName  = craft()->request->getPost('customerName');
          $charge->customerEmail = craft()->request->getPost('customerEmail');
  
          $charge->planAmount    = 10000; // In cents
  
          if ($charge->validate() && craft()->charge->handlePayment($charge))
          {
              // Save the booking entry
              $entry = new EntryModel();
              $entry->sectionId = craft()->request->getPost('sectionId');
              $entry->typeId    = craft()->request->getPost('typeId'); // Not necessary if there's only one entry type
              $entry->authorId  = $user->id;
              $entry->enabled   = true;
  
              $entry->getContent()->title = 'New Booking: '.$user->username;
              $entry->getContent()->chargeId = $charge->id; // Custom number field
              $entry->getContent()->someOtherCustomField = 'xyz';
  
              craft()->entries->saveEntry($entry);
  
              // Redirect the request based on the 'redirect' param
              craft()->userSession->setNotice('Booking saved.');
              $this->redirectToPostedUrl();
          }
          else
          {
              craft()->userSession->setError('Couldn’t charge the card.');
  
              // Send the charge model to the template
              craft()->urlManager->setRouteVariables(array(
                  'charge' => $charge
              ));
          }
      }
  }
  
  ```
  
  You might want to hard-code the sectionId and typeId rather than leaving it up to the POST data, and there might be other slight changes you want to make, but that’s the gist.
  
  With the plugin in place, you would just need to create a form that captures all of the info the controller is looking for, and posts it to the `foo/createBooking` action:
  
  ```html
  <form method="post" accept-charset="UTF-8">
      {{ getCsrfInput() }}
      <input type="hidden" name="action" value="foo/createBooking">
  
      <!-- ... -->
  </form>
  
  ```
  
  > **Comments:**
  > **username_0**: Thank you so much username_2 - saved me time and money posting that. And I've got a better idea of how the plugin stuff works together after seeing a live example. I did hardcode the section ID after all, and I see how the custom fields work. Brilliant!  
  > **username_3**: Exactly what username_2 said. I've implemented that same solution a number of times for projects (and while it's semi-obvious when you know what's going on it's not always clear this approach can work for basically any similar setup).  
  > **username_0**: Hi username_3/username_2 - just revisiting this now and I've realised that the {hash} from the payment form (charge/success/{hash}) doesn't work when using the plugin as an action instead of charge/charge - it sends the user to /charge/success/%7Bhash%7D. Is there a way to get the plugin to pull in the hash from Charge?  
  > **username_3**: @DarylKnight If you're running your own controller infront of the charge payment you can adjust the redirect directly after the craft()->charge->handlePayment returns. I couldn't say exactly why the {hash} isn't automatically parsing in your case, that specific variable replacement is inherited from Craft's internal request controllers not something Charge is doing specially.  
  > **username_0**: No problem, thanks for getting back to me!  
  > **username_3**: Just to update this comment above about {hash} not being properly parsed out, it's just a case of making sure you pass the object to the redirectToPostedUrl() method, so, in this case that'd be : $this->redirectToPostedUrl($charge)  
  
  ---
  
  ### Answer by username_1 on 2014-10-08. Score: 1
  
  Currently, you will have to either use a plugin, or dump all your content into a notes field given by Charge (this would require JS coding). There are new features coming up in 2.0, but you would need to talk to [username_3 over at Square Bit](http://squarebit.co.uk/) for any details. If this is a crucial feature, you can hire a Craft developer over at [Straight Up Craft](http://straightupcraft.com/professionals).
  
  
  ---
  
  