8 replies [Last post]
sigsegv's picture
Offline
Joined: 08/26/2009
Juice: 4
Was this information Helpful?

Is there a recipe/tutorial out there for Ubercart on setting up Pay Per Post?

I have a content type/node setup where I want users to have to pay every time they go to create content for it. they click to create content for this type it then asks them for a fee they input whatever necessary payment information then they're given 1 time access to add this content. Then later "this same user" wants to make another post it's a repeat of the same process where he pays a fee again and makes the post.

jazzdrive3's picture
Offline
Joined: 03/29/2009
Juice: 221
Look at UC Node Checkout. If

Look at UC Node Checkout.

If you need something more flexible, however, you'll need to write a module yourself.

I did something where I wanted the node to be created, but unpublished. And then once they paid, that node was published. If you want to skip the cart, just use hook_form_alter, add a submit handler that adds an item to the cart, and set the node edit form redirect to the checkout page.

//new submit handler for node creation form
uc_cart_add_item($node_id_of_product);

//inside form_alter, set it to redirect to checkout after submit.
$form['#redirect']='cart/checkout';

dorien's picture
Offline
Joined: 01/28/2009
Juice: 88
Re: Look at UC Node Checkout. If

I am looking for something similar, so use with a ticketing module, where users pay a fixed amount to submit a support ticket.

zeezhao's picture
Offline
Joined: 04/23/2008
Juice: 969
Re: Re: Look at UC Node Checkout. If

Hi. Interested in how you got this done, as I have a similar scenario.

The alternative I have in mind is to use userpoints in conjunction with userpoints_node_action and userpoints_ubercart modules. In this solution, Users will purchase userpoints via ubercart for a fixed amount, and then the userpoints_node_action module will control deduction of points for publishing a node (or support ticket).

jrowny's picture
Offline
Joined: 01/08/2009
Juice: 297
Re: Re: Re: Look at UC Node Checkout. If

I wrote something where they can freely create any content, but to "activate" it, they had to pay.

Basically, I made one product called "contest entry." They submitted several contest entries (songs) and then when they click the product page it calculates their total based on how many entries they made. I did that with the "custom price" module.

Finally, when the order is successful, I run a query to update all their current contest entries.

If that works for you, I could share the code.

jrowny's picture
Offline
Joined: 01/08/2009
Juice: 297
Re: Re: Re: Re: Look at UC Node Checkout. If

btw, the main reason I did it this way was because the price was less the more entries you made. SO if you make 10 entries, it's a lot cheaper than just one.

It keeps track of which entries are paid for using a hidden CCK field. It can display on the user's "manage entries" page which entries they have paid for.

zeezhao's picture
Offline
Joined: 04/23/2008
Juice: 969
Re: Pay Per Post?

Thanks, jrowny. It would be helpful to see the code/module.

jrowny's picture
Offline
Joined: 01/08/2009
Juice: 297
Re: Re: Pay Per Post?

So I created one product. This product uses the custom price module with the following code in the custom price field:

global $user;

$postsToPayFor = db_query("SELECT count(n.nid) as nCount
FROM {content_type_song} s LEFT JOIN {node} n on n.nid = s.nid  WHERE n.uid = %d and n.type = 'song' and (s.field_paid_value is NULL or s.field_paid_value = 'Unpaid')", $user->uid);
$postsToCount = db_query("SELECT count(n.nid) as nCount
FROM {node} n WHERE n.uid = %d and n.type = 'song'", $user->uid);

$postCount = db_result($postsToPayFor);
$postCountOverall = db_result($postsToCount);

   if($postCountOverall < 5){
      $item->price = $postCount * 20;
   }else if($postCountOverall < 11){
      $item->price = $postCount * 18;
   }else{
      $item->price = $postCount * 15;
   }

This is a bit confusing, but basically every time they buy an entry, the price goes down. So you need to query to see how many entries they've ever made.

Next you just make a page with some code that displays whether or not you have posts to pay for, and how much you pay for them.

<?php
global $user;

$songsToPay = db_query("SELECT count(n.nid) as nCount
FROM {content_type_song} s LEFT JOIN {node} n on n.nid = s.nid  WHERE n.uid = %d and n.type = 'song' and (s.field_paid_value is NULL or s.field_paid_value = 'Unpaid')"
, $user->uid);
$songsToCount = db_query("SELECT count(n.nid) as nCount
FROM {node} n WHERE n.uid = %d and n.type = 'song'"
, $user->uid);

$songCount = db_result($songsToPay);
$songCountOverall = db_result($songsToCount);

$cost = 0;

   if(

$songCountOverall < 5){
     
$cost  = $songCount * 20;
   }else if(
$songCountOverall < 11){
     
$cost = $songCount * 18;
   }else{
     
$cost  = $songCount * 15;
   }

?>

<?php if($songCount):?>
<span style="font-size:14px;">
You currently have <?php print $songCount; ?> unpaid songs. Your total entry fee is <strong><?php print uc_currency_format($cost); ?>.</strong> <br/><strong>
<a href="<?php print base_path() ?>cart/add/e-p5_q1_a1o<?php print $songCount ?>_m0?destination=cart/checkout"><img src="<?php print base_path() . path_to_theme(); ?>/images/checkout.png" alt="Continue to Checkout"/></a></strong>
</span>
<?php else:?>
<h2>You do not have any songs to pay for. Please <?php print l("submit","node/add/song"); ?> a song first.</h2>
<?php endif;?>

On your site, you just link to this page. I used the PHP filter to make this page.

The last step is to create a "conditional action" called "set content to paid" under the "Customer completes checkout" section.

In the "action" put "custom php" and here is the code for that.

watchdog("post-mark-paid","attempting to pay for songs");
foreach($order->products as $product){
foreach($product->data['attributes'] as $key => $value){
watchdog("song-upgrade","songs to upgrade:" . $value . "on account id:" . $account->uid);
//$value == number of songs
db_query("update {content_type_song} set field_paid_value = 'Paid'
where nid in
(select nid from

(select n.nid from {node} n left join {content_type_song} s on s.nid = n.nid where type='song' and n.uid = " . $account->uid . " and
    (s.field_paid_value is null or s.field_paid_value = 'Unpaid')
) as temp

) LIMIT " . $value);
watchdog("post-mark-paid","query executed");
}
}

Now this code is a bit ugly, I loop through the cart which should only have one item. I don't remember why on earth I had to loop through the cart and attributes when you only have one item and one attribute but probably because I didn't know the array key was nor how to find out. When I wrote this I was still pretty noobish.

We did over 1,000 paid entries in our contest without any major issues. There were a few people who had trouble uploading their MP3 files but it was mostly user error.

zeezhao's picture
Offline
Joined: 04/23/2008
Juice: 969
Re: Pay Per Post?

Thanks for this!