Permalink
Browse files

check for transactions more often

  • Loading branch information...
1 parent 48d080b commit a7053b8a78c3ece3e20956c274d782862aae762a Luke Closs committed Jun 13, 2012
Showing with 186 additions and 168 deletions.
  1. +11 −162 bin/job-runner
  2. +172 −0 bin/process-transactions
  3. +0 −4 lib/Biopay/Daemon.pm
  4. +3 −2 lib/Biopay/Member.pm
View
@@ -37,8 +37,7 @@ my $daemon = Biopay::Daemon->new(
print " (Receipt to @{[$member->id]} - @{[$member->name]}) ";
# Shell out so we can avoid AE-style programming of the
# receipt code
- system($^X, "$FindBin::Bin/send-receipt", $job->_id)
- and die "Could not send receipt for job " . $job->_id;
+ run('send-receipt', $job->_id);
},
'register-member' => sub {
my ($job, $member) = @_;
@@ -50,13 +49,12 @@ my $daemon = Biopay::Daemon->new(
print " (Protest for @{[$member->id]}) ";
# Shell out so we can avoid AE-style programming of the
# receipt code
- system($^X, "$FindBin::Bin/send-protest", $member->id, ($cc_member ? '--cc' : ()))
- and die "Could not send protest for member " . $member->id;
+ run('send-protest', $member->id, ($cc_member ? '--cc' : ()));
},
},
CVs => [
AnyEvent->timer(
- after => 2.0, interval => 600,
+ after => 2.0, interval => 60,
cb => \&check_for_unpaid_txns,
),
],
@@ -186,9 +184,10 @@ sub check_for_unpaid_txns {
print " (No member $mid found) ";
return;
}
+ return if $member->billing_error;
if (my $hash = $member->payment_hash) {
- process_transactions($member, $txns)
- unless $member->billing_error;
+ print 'P';
+ run("process-transactions", $member->id);
}
else {
print 'u';
@@ -200,160 +199,10 @@ sub check_for_unpaid_txns {
);
}
-sub process_transactions {
- my $member = shift;
- my $txns = shift;
- return unless @$txns;
- my $total = sum map { $_->price } @$txns;
- print ' (Bio-' . $member->id . ":\$$total) ";
- my $items = [
- map { { amount => $_->price, type => 'txn', desc => $_->txn_id } }
- @$txns
- ];
-
- my $order_num = @$txns > 1
- ? sprintf("%d-txns-%d", @$txns+0, time)
- : "txn-" . $txns->[0]->txn_id;
-
- my $need_to_renew_membership = $member->membership_is_expired;
- my $membership_price = $daemon->prices->annual_membership_price;
- if ($need_to_renew_membership) {
- $total += $membership_price;
- push @$items, {
- amount => $membership_price,
- type => 'dues',
- desc => 'Membership Dues',
- };
- }
-
- my $error = "Order '$order_num' not yet processed.";
- try {
- try {
- $daemon->processor->process(
- order_num => $order_num,
- amount => $total,
- hash => $member->payment_hash,
- );
- Biopay::Receipt->Create(
- member_id => $member->id,
- order_num => $order_num,
- amount => $total,
- items => $items,
- );
-
- # Update the member, if necessary
- if ($need_to_renew_membership) {
- $member->renew_membership(
- success_cb => sub {
- print ' (Renewed membership for: ' . $member->id . ') ';
- unfreeze_member($member) if $member->frozen;
- },
- error_cb => sub {
- my $save_err = shift;
- email_admin("Failed to renew membership",
- "I tried to renew member " . $member->id
- . "'s dues, but the save failed: $save_err");
- unfreeze_member($member) if $member->frozen;
- },
- );
- }
- else {
- unfreeze_member($member) if $member->frozen;
- }
- }
- catch {
- my $err = $_;
- # There was an error processing payment for this member. Set their
- # billing_error flag, so that we don't retry until it is cleared
- $member->billing_error($err);
- $member->frozen(1);
- create_freeze_job($member, 'freeze');
- $member->save(
- success_cb => sub {
- print ' (Freeze:' . $member->id . ') ';
- },
- error_cb => sub {
- my $save_err = shift;
- email_admin("Failed to set billing_error for member",
- "I tried to mark member " . $member->id . " with a "
- . "billing error for order '$order_num' but failed."
- . "\nSave error was: $save_err"
- . "\nPayment error was: $err");
- },
- );
- $member->send_billing_error_email($err, $total);
-
- # Re-raise error so that it is reported properly.
- die $err;
- };
-
- $error = "Order '$order_num' processed but txns not marked as paid.";
- for my $txn (@$txns) {
- print " (Marking " . $txn->id . " as paid) ";
- $txn->paid(1);
- $txn->save(
- error_cb => sub {
- my $err = shift;
- email_admin("Failed to mark txn:" . $txn->id . " as paid!",
- "I was trying to mark it as paid after successfully "
- . " processing order $order_num for \$$total\n\n$err"
- );
- }
- );
- }
- $error = "Order '$order_num' processed, txns marked as paid, but "
- . "receipt is not sent.";
-
- Biopay::Command->Create(
- command => 'send-receipt',
- member_id => $member->id,
- txn_ids => [ map { $_->id } @$txns ],
- ($need_to_renew_membership ? (dues => $membership_price) : ())
- );
- }
- catch {
- my $err = $_;
- error $err;
-
- email_admin("Error processing payment $order_num",
- "Had a problem during payment processing: $error\n\n$err\n\n"
- . "This payment was for member ID " . $member->id
- . " (" . host() . '/members/' . $member->id . ') '
- . " for transactions: " . join(', ', map { host() . '/txns/' . $_->id } @$txns)
- );
- }
-}
-
-sub create_freeze_job {
- my $member = shift;
- my $type = shift;
- Biopay::Command->Create(
- command => $type,
- member_id => $member->id,
- on_error => sub {
- my $err = shift;
- email_admin("Failed to $type @{[$member->id]}",
- "I failed to create a $type job for $member->id.\n\n"
- . "Error: $err");
- },
- );
-}
-sub unfreeze_member {
- my $member = shift;
- $member->frozen(0);
- create_freeze_job($member, 'unfreeze');
-
- $member->save(
- success_cb => sub {
- print ' (Un-freeze:' . $member->id . ') ';
- },
- error_cb => sub {
- my $err = shift;
- email_admin("Failed to un-freeze member",
- "I tried to un-freeze member " . $member->id
- . " after a successful payment, but saving failed."
- . "\nError was: $err");
- },
- );
+sub run {
+ my $cmd = shift;
+ warn "Running '$cmd @_'\n";
+ system($^X, "$FindBin::Bin/$cmd", @_)
+ and die "Failed to run: $cmd";
}
View
@@ -0,0 +1,172 @@
+#!/usr/bin/env perl
+use 5.14.1;
+use Dancer qw/:syntax/;
+use Dancer::Plugin::Email;
+use FindBin;
+use Cwd qw/realpath/;
+use lib "$FindBin::Bin/../lib";
+use Biopay::Member;
+use Biopay::Prices;
+use Biopay::PaymentProcessor;
+use Biopay::Receipt;
+use Getopt::Long;
+
+BEGIN {
+ Dancer::Config::setting('appdir',realpath("$FindBin::Bin/.."));
+ Dancer::Config::setting('views',realpath("$FindBin::Bin/../views"));
+ Dancer::Config::load();
+}
+
+my $member_id = shift || die "USAGE: $0 <member_id>";;
+my $member = Biopay::Member->By_id($member_id);
+my $txns = $member->unpaid_transactions;
+unless (@$txns) {
+ print "Member $member_id has no un-paid transactions.\n";
+ exit;
+}
+
+my $total = sum map { $_->price } @$txns;
+print ' (Bio-' . $member->id . ":\$$total) ";
+my $items = [
+ map { { amount => $_->price, type => 'txn', desc => $_->txn_id } }
+ @$txns
+];
+
+my $order_num = @$txns > 1
+ ? sprintf("%d-txns-%d", @$txns+0, time)
+ : "txn-" . $txns->[0]->txn_id;
+
+my $need_to_renew_membership = $member->membership_is_expired;
+my $membership_price = Biopay::Prices->new->annual_membership_price;
+if ($need_to_renew_membership) {
+ $total += $membership_price;
+ push @$items, {
+ amount => $membership_price,
+ type => 'dues',
+ desc => 'Membership Dues',
+ };
+}
+
+my $error = "Order '$order_num' not yet processed.";
+try {
+ try {
+ Biopay::PaymentProcessor->new->process(
+ order_num => $order_num,
+ amount => $total,
+ hash => $member->payment_hash,
+ );
+ Biopay::Receipt->Create(
+ member_id => $member->id,
+ order_num => $order_num,
+ amount => $total,
+ items => $items,
+ );
+
+ $error = "Processed payment, but didn't update member yet.";
+ # Update the member, if necessary
+ if ($need_to_renew_membership) {
+ $member->renew_membership;
+ print ' (Renewed membership for: ' . $member->id . ') ';
+ }
+ unfreeze_member($member) if $member->frozen;
+ }
+ catch {
+ my $err = $_;
+ # There was an error processing payment for this member. Set their
+ # billing_error flag, so that we don't retry until it is cleared
+ $member->billing_error($err);
+ $member->billing_error_epoch(time());
+ $member->frozen(1);
+ create_freeze_job($member, 'freeze');
+ try {
+ $member->save;
+ print ' (Freeze:' . $member->id . ') ';
+ }
+ catch {
+ my $save_err = $_;
+ email_admin("Failed to set billing_error for member",
+ "I tried to mark member " . $member->id . " with a "
+ . "billing error for order '$order_num' but failed."
+ . "\nSave error was: $save_err"
+ . "\nPayment error was: $err");
+ };
+ $member->send_billing_error_email($err, $total);
+
+ # Re-raise error so that it is reported properly.
+ die $err;
+ };
+
+ $error = "Order '$order_num' processed but txns not marked as paid.";
+ for my $txn (@$txns) {
+ print " (Marking " . $txn->id . " as paid) ";
+ $txn->paid(1);
+ try {
+ $txn->save;
+ }
+ catch {
+ my $err = $_;
+ email_admin("Failed to mark txn:" . $txn->id . " as paid!",
+ "I was trying to mark it as paid after successfully "
+ . " processing order $order_num for \$$total\n\n$err"
+ );
+ };
+ }
+ $error = "Order '$order_num' processed, txns marked as paid, but "
+ . "receipt is not sent.";
+
+ Biopay::Command->Create(
+ command => 'send-receipt',
+ member_id => $member->id,
+ txn_ids => [ map { $_->id } @$txns ],
+ ($need_to_renew_membership ? (dues => $membership_price) : ())
+ );
+}
+catch {
+ my $err = $_;
+ error $err;
+
+ email_admin("Error processing payment $order_num",
+ "Had a problem during payment processing: $error\n\n$err\n\n"
+ . "This payment was for member ID " . $member->id
+ . " (" . host() . '/members/' . $member->id . ') '
+ . " for transactions: " . join(', ', map { host() . '/txns/' . $_->id } @$txns)
+ );
+}
+
+exit;
+
+sub create_freeze_job {
+ my $member = shift;
+ my $type = shift;
+ try {
+ Biopay::Command->Create(
+ command => $type,
+ member_id => $member->id,
+ );
+ }
+ catch {
+ my $err = $_;
+ email_admin("Failed to $type @{[$member->id]}",
+ "I failed to create a $type job for $member->id.\n\n"
+ . "Error: $err");
+ };
+}
+
+sub unfreeze_member {
+ my $member = shift;
+ $member->frozen(0);
+ create_freeze_job($member, 'unfreeze');
+
+ try {
+ $member->save;
+ print ' (Un-freeze:' . $member->id . ') ';
+ }
+ catch {
+ my $err = $_;
+ email_admin("Failed to un-freeze member",
+ "I tried to un-freeze member " . $member->id
+ . " after a successful payment, but saving failed."
+ . "\nError was: $err");
+ };
+}
+
View
@@ -8,7 +8,6 @@ use Try::Tiny;
use AnyEvent;
use Dancer::Plugin::CouchDB;
use AnyEvent::CouchDB::Stream;
-use Biopay::PaymentProcessor;
use Biopay::Util qw/email_admin/;
use Biopay::Command;
use Biopay::Prices;
@@ -33,7 +32,6 @@ has 'prices' => (is => 'ro', isa => 'Object', default => sub {
has 'want_stream' => (is => 'ro', isa => 'Bool', default => sub { 0 });
has 'couch' => (is => 'ro', isa => 'Object', lazy_build => 1);
-has 'processor' => (is => 'ro', isa => 'Object', lazy_build => 1);
has 'stream' => (is => 'rw', isa => 'Maybe[Object]');
has '_last_seq' => (is => 'rw', isa => 'Num', default => 0);
@@ -197,5 +195,3 @@ method _build_couch {
die "Could not connect to the couch!" unless $couch;
return $couch;
}
-
-method _build_processor { Biopay::PaymentProcessor->new }
Oops, something went wrong.

0 comments on commit a7053b8

Please sign in to comment.