| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # package: WebService::Dwolla | 
| 2 |  |  |  |  |  |  | #   Perl module to interact with Dwolla's OAuth+REST API | 
| 3 |  |  |  |  |  |  | package WebService::Dwolla; | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 1 |  |  | 1 |  | 23843 | use 5.010001; | 
|  | 1 |  |  |  |  | 4 |  | 
|  | 1 |  |  |  |  | 37 |  | 
| 6 | 1 |  |  | 1 |  | 6 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 32 |  | 
| 7 | 1 |  |  | 1 |  | 6 | use warnings; | 
|  | 1 |  |  |  |  | 6 |  | 
|  | 1 |  |  |  |  | 53 |  | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | our $VERSION = '0.05'; | 
| 10 |  |  |  |  |  |  |  | 
| 11 | 1 |  |  | 1 |  | 2703 | use LWP::UserAgent; | 
|  | 1 |  |  |  |  | 91770 |  | 
|  | 1 |  |  |  |  | 43 |  | 
| 12 | 1 |  |  | 1 |  | 1293 | use JSON; | 
|  | 1 |  |  |  |  | 17242 |  | 
|  | 1 |  |  |  |  | 7 |  | 
| 13 | 1 |  |  | 1 |  | 348 | use URI::Escape; | 
|  | 1 |  |  |  |  | 5 |  | 
|  | 1 |  |  |  |  | 106 |  | 
| 14 | 1 |  |  | 1 |  | 1148 | use Digest::HMAC; | 
|  | 1 |  |  |  |  | 649 |  | 
|  | 1 |  |  |  |  | 52 |  | 
| 15 | 1 |  |  | 1 |  | 1369 | use IO::File; | 
|  | 1 |  |  |  |  | 11167 |  | 
|  | 1 |  |  |  |  | 169 |  | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | use constant { | 
| 18 | 1 |  |  |  |  | 5123 | API_SERVER   => 'https://www.dwolla.com/oauth/rest', | 
| 19 |  |  |  |  |  |  | AUTH_URL     => 'https://www.dwolla.com/oauth/v2/authenticate', | 
| 20 |  |  |  |  |  |  | TOKEN_URL    => 'https://www.dwolla.com/oauth/v2/token', | 
| 21 |  |  |  |  |  |  | GATEWAY_URL  => 'https://www.dwolla.com/payment/request', | 
| 22 |  |  |  |  |  |  | CHECKOUT_URL => 'https://www.dwolla.com/payment/checkout', | 
| 23 |  |  |  |  |  |  | MASSPAY_URL  => 'https://masspay.dwollalabs.com/api' | 
| 24 | 1 |  |  | 1 |  | 9 | }; | 
|  | 1 |  |  |  |  | 2 |  | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | # Function: new | 
| 27 |  |  |  |  |  |  | # | 
| 28 |  |  |  |  |  |  | # Constructor. | 
| 29 |  |  |  |  |  |  | # | 
| 30 |  |  |  |  |  |  | # Parameters: | 
| 31 |  |  |  |  |  |  | #   self         - Object instance. | 
| 32 |  |  |  |  |  |  | #   key          - API key | 
| 33 |  |  |  |  |  |  | #   secret       - API secret | 
| 34 |  |  |  |  |  |  | #   redirect_uri - OAuth redirect URL | 
| 35 |  |  |  |  |  |  | #   permissions  - Application permissions | 
| 36 |  |  |  |  |  |  | #   mode         - Mode. Default: 'live' | 
| 37 |  |  |  |  |  |  | #   debug_mode   - Debug mode. Default: 0 (Off) | 
| 38 |  |  |  |  |  |  | # | 
| 39 |  |  |  |  |  |  | # Returns: | 
| 40 |  |  |  |  |  |  | #   Object instance. | 
| 41 |  |  |  |  |  |  | sub new | 
| 42 |  |  |  |  |  |  | { | 
| 43 | 0 |  |  | 0 | 0 |  | my $class        = shift; | 
| 44 | 0 |  | 0 |  |  |  | my $key          = shift || undef; | 
| 45 | 0 |  | 0 |  |  |  | my $secret       = shift || undef; | 
| 46 | 0 |  | 0 |  |  |  | my $redirect_uri = shift || undef; | 
| 47 | 0 |  | 0 |  |  |  | my $permissions  = shift || ['send','transactions','balance','request','contacts','accountinfofull','funding']; | 
| 48 | 0 |  | 0 |  |  |  | my $mode         = shift || 'live'; | 
| 49 | 0 |  | 0 |  |  |  | my $debug_mode   = shift || 0; | 
| 50 |  |  |  |  |  |  |  | 
| 51 | 0 |  |  |  |  |  | my $self  = {}; | 
| 52 |  |  |  |  |  |  |  | 
| 53 | 0 |  |  |  |  |  | $self->{'api_key'}      = $key; | 
| 54 | 0 |  |  |  |  |  | $self->{'api_secret'}   = $secret; | 
| 55 | 0 |  |  |  |  |  | $self->{'permissions'}  = $permissions; | 
| 56 | 0 |  |  |  |  |  | $self->{'mode'}         = $mode; | 
| 57 | 0 |  |  |  |  |  | $self->{'errors'}       = []; | 
| 58 | 0 |  |  |  |  |  | $self->{'redirect_uri'} = $redirect_uri; | 
| 59 | 0 |  |  |  |  |  | $self->{'debug_mode'}   = $debug_mode; | 
| 60 |  |  |  |  |  |  |  | 
| 61 | 0 |  |  |  |  |  | bless($self,$class); | 
| 62 |  |  |  |  |  |  |  | 
| 63 | 0 |  |  |  |  |  | return $self; | 
| 64 |  |  |  |  |  |  | } | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | # Function: set_api_config_from_file | 
| 67 |  |  |  |  |  |  | # | 
| 68 |  |  |  |  |  |  | # Sets required API information from configuration file. | 
| 69 |  |  |  |  |  |  | #   key=APIKEY | 
| 70 |  |  |  |  |  |  | #   secret=APISECRET | 
| 71 |  |  |  |  |  |  | #   token=OAUTHTOKEN | 
| 72 |  |  |  |  |  |  | # | 
| 73 |  |  |  |  |  |  | # Parameters: | 
| 74 |  |  |  |  |  |  | #   self - Object instance. | 
| 75 |  |  |  |  |  |  | #   file - Filename of configuaretion. | 
| 76 |  |  |  |  |  |  | # | 
| 77 |  |  |  |  |  |  | # Returns: | 
| 78 |  |  |  |  |  |  | #   true (1) on success and false (0) on failure. | 
| 79 |  |  |  |  |  |  | sub set_api_config_from_file | 
| 80 |  |  |  |  |  |  | { | 
| 81 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 82 | 0 |  |  |  |  |  | my $file = shift; | 
| 83 |  |  |  |  |  |  |  | 
| 84 | 0 |  |  |  |  |  | my $config = IO::File->new($file,'r'); | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 0 | 0 |  |  |  |  | if (!defined($config)) { | 
| 87 | 0 |  |  |  |  |  | return 0; | 
| 88 |  |  |  |  |  |  | } | 
| 89 |  |  |  |  |  |  |  | 
| 90 | 0 |  |  |  |  |  | while(!$config->eof()) { | 
| 91 | 0 |  |  |  |  |  | my $line = $config->getline(); | 
| 92 | 0 |  |  |  |  |  | $line =~ s/\n//g; | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 0 |  |  |  |  |  | my ($key,$value) = split(/\=/,$line); | 
| 95 |  |  |  |  |  |  |  | 
| 96 | 0 | 0 |  |  |  |  | if ($key eq 'key') { | 
| 97 | 0 |  |  |  |  |  | $self->{'api_key'} = $value; | 
| 98 |  |  |  |  |  |  | } | 
| 99 |  |  |  |  |  |  |  | 
| 100 | 0 | 0 |  |  |  |  | if ($key eq 'secret') { | 
| 101 | 0 |  |  |  |  |  | $self->{'api_secret'} = $value; | 
| 102 |  |  |  |  |  |  | } | 
| 103 |  |  |  |  |  |  |  | 
| 104 | 0 | 0 |  |  |  |  | if ($key eq 'token') { | 
| 105 | 0 |  |  |  |  |  | $self->{'oauth_token'} = $value; | 
| 106 |  |  |  |  |  |  | } | 
| 107 |  |  |  |  |  |  | } | 
| 108 |  |  |  |  |  |  |  | 
| 109 | 0 |  |  |  |  |  | $config->close(); | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | # Function: get_auth_url | 
| 113 |  |  |  |  |  |  | # | 
| 114 |  |  |  |  |  |  | # Gets OAuth URL | 
| 115 |  |  |  |  |  |  | # | 
| 116 |  |  |  |  |  |  | # Parameters: | 
| 117 |  |  |  |  |  |  | #   self - Object instance. | 
| 118 |  |  |  |  |  |  | # | 
| 119 |  |  |  |  |  |  | # Returns: | 
| 120 |  |  |  |  |  |  | #   OAuth URL | 
| 121 |  |  |  |  |  |  | sub get_auth_url | 
| 122 |  |  |  |  |  |  | { | 
| 123 | 0 |  |  | 0 | 0 |  | my $self  = shift; | 
| 124 |  |  |  |  |  |  |  | 
| 125 | 0 |  |  |  |  |  | my $params = { | 
| 126 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 127 |  |  |  |  |  |  | 'response_type' => 'code', | 
| 128 | 0 |  |  |  |  |  | 'scope'         => join('|',@{$self->{'permissions'}}) | 
| 129 |  |  |  |  |  |  | }; | 
| 130 |  |  |  |  |  |  |  | 
| 131 | 0 | 0 |  |  |  |  | if (defined($self->{'redirect_uri'})) { | 
| 132 | 0 |  |  |  |  |  | $params->{'redirect_uri'} = $self->{'redirect_uri'}; | 
| 133 |  |  |  |  |  |  | } | 
| 134 |  |  |  |  |  |  |  | 
| 135 | 0 |  |  |  |  |  | my $url = AUTH_URL . '/?' . $self->_http_build_query($params); | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 0 |  |  |  |  |  | return $url; | 
| 138 |  |  |  |  |  |  | } | 
| 139 |  |  |  |  |  |  |  | 
| 140 |  |  |  |  |  |  | # Function: request_token | 
| 141 |  |  |  |  |  |  | # | 
| 142 |  |  |  |  |  |  | # Request OAuth token from Dwolla. | 
| 143 |  |  |  |  |  |  | # | 
| 144 |  |  |  |  |  |  | # Parameters: | 
| 145 |  |  |  |  |  |  | #   self - Object instance. | 
| 146 |  |  |  |  |  |  | #   code - Temporary code from Dwolla. | 
| 147 |  |  |  |  |  |  | # | 
| 148 |  |  |  |  |  |  | # Returns: | 
| 149 |  |  |  |  |  |  | #   OAuth token. | 
| 150 |  |  |  |  |  |  | sub request_token | 
| 151 |  |  |  |  |  |  | { | 
| 152 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 153 | 0 |  |  |  |  |  | my $code = shift; | 
| 154 |  |  |  |  |  |  |  | 
| 155 | 0 | 0 |  |  |  |  | if (!defined($code)) { | 
| 156 | 0 |  |  |  |  |  | $self->set_error('Please pass a valid OAuth code.'); | 
| 157 | 0 |  |  |  |  |  | return 0; | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 0 |  |  |  |  |  | my $params = { | 
| 161 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 162 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 163 |  |  |  |  |  |  | 'redirect_uri'  => $self->{'redirect_uri'}, | 
| 164 |  |  |  |  |  |  | 'grant_type'    => 'authorization_code', | 
| 165 |  |  |  |  |  |  | 'code'          => $code | 
| 166 |  |  |  |  |  |  | }; | 
| 167 |  |  |  |  |  |  |  | 
| 168 | 0 |  |  |  |  |  | my $url = TOKEN_URL . '?' . $self->_http_build_query($params); | 
| 169 |  |  |  |  |  |  |  | 
| 170 | 0 |  |  |  |  |  | my $response = $self->_api_request($url,'GET'); | 
| 171 |  |  |  |  |  |  |  | 
| 172 | 0 | 0 |  |  |  |  | if ($response->{'error'}) { | 
| 173 | 0 |  |  |  |  |  | $self->set_error($response->{'error_description'}); | 
| 174 | 0 |  |  |  |  |  | return 0; | 
| 175 |  |  |  |  |  |  | } | 
| 176 |  |  |  |  |  |  |  | 
| 177 | 0 |  |  |  |  |  | return $response->{'access_token'}; | 
| 178 |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | # Function: set_token | 
| 181 |  |  |  |  |  |  | # | 
| 182 |  |  |  |  |  |  | # Manually set OAuth token. | 
| 183 |  |  |  |  |  |  | # | 
| 184 |  |  |  |  |  |  | # Parameters: | 
| 185 |  |  |  |  |  |  | #   self  - Object instance. | 
| 186 |  |  |  |  |  |  | #   token - Existing OAuth token. | 
| 187 |  |  |  |  |  |  | # | 
| 188 |  |  |  |  |  |  | # Returns: | 
| 189 |  |  |  |  |  |  | #   Void | 
| 190 |  |  |  |  |  |  | sub set_token | 
| 191 |  |  |  |  |  |  | { | 
| 192 | 0 |  |  | 0 | 0 |  | my $self  = shift; | 
| 193 | 0 |  |  |  |  |  | my $token = shift; | 
| 194 |  |  |  |  |  |  |  | 
| 195 | 0 |  |  |  |  |  | $self->{'oauth_token'} = $token; | 
| 196 |  |  |  |  |  |  | } | 
| 197 |  |  |  |  |  |  |  | 
| 198 |  |  |  |  |  |  | # Function: set_mode | 
| 199 |  |  |  |  |  |  | # | 
| 200 |  |  |  |  |  |  | # Set mode. | 
| 201 |  |  |  |  |  |  | # | 
| 202 |  |  |  |  |  |  | # Parameters: | 
| 203 |  |  |  |  |  |  | #   self - Object instance. | 
| 204 |  |  |  |  |  |  | #   mode - Mode ('test' / 'live'). | 
| 205 |  |  |  |  |  |  | # | 
| 206 |  |  |  |  |  |  | # Returns: | 
| 207 |  |  |  |  |  |  | #   Void or false (0) on error. | 
| 208 |  |  |  |  |  |  | sub set_mode | 
| 209 |  |  |  |  |  |  | { | 
| 210 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 211 | 0 |  |  |  |  |  | my $mode = shift; | 
| 212 |  |  |  |  |  |  |  | 
| 213 | 0 | 0 | 0 |  |  |  | if ($mode ne 'test' && $mode ne 'live') { | 
| 214 | 0 |  |  |  |  |  | $self->set_error("Invalid mode. Please use 'test' / 'live'."); | 
| 215 | 0 |  |  |  |  |  | return 0; | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 | 0 |  |  |  |  |  | $self->{'mode'} = $mode; | 
| 219 |  |  |  |  |  |  | } | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | # Function: get_mode | 
| 222 |  |  |  |  |  |  | # | 
| 223 |  |  |  |  |  |  | # Get mode. | 
| 224 |  |  |  |  |  |  | # | 
| 225 |  |  |  |  |  |  | # Parameters: | 
| 226 |  |  |  |  |  |  | #   self - Object instance. | 
| 227 |  |  |  |  |  |  | # | 
| 228 |  |  |  |  |  |  | # Returns: | 
| 229 |  |  |  |  |  |  | #   Mode | 
| 230 |  |  |  |  |  |  | sub get_mode | 
| 231 |  |  |  |  |  |  | { | 
| 232 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 233 |  |  |  |  |  |  |  | 
| 234 | 0 |  |  |  |  |  | return $self->{'mode'}; | 
| 235 |  |  |  |  |  |  | } | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | # Function: get_token | 
| 238 |  |  |  |  |  |  | # | 
| 239 |  |  |  |  |  |  | # Get current OAuth token. | 
| 240 |  |  |  |  |  |  | # | 
| 241 |  |  |  |  |  |  | # Parameters: | 
| 242 |  |  |  |  |  |  | #   self  - Object instance. | 
| 243 |  |  |  |  |  |  | #   token - Existing OAuth token. | 
| 244 |  |  |  |  |  |  | # | 
| 245 |  |  |  |  |  |  | # Returns: | 
| 246 |  |  |  |  |  |  | #   OAuth token | 
| 247 |  |  |  |  |  |  | sub get_token | 
| 248 |  |  |  |  |  |  | { | 
| 249 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 250 |  |  |  |  |  |  |  | 
| 251 | 0 |  |  |  |  |  | return $self->{'oauth_token'}; | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | # Function: me | 
| 255 |  |  |  |  |  |  | # | 
| 256 |  |  |  |  |  |  | # Gets information about user with token. | 
| 257 |  |  |  |  |  |  | # | 
| 258 |  |  |  |  |  |  | # Parameters: | 
| 259 |  |  |  |  |  |  | #   self - Object instance. | 
| 260 |  |  |  |  |  |  | # | 
| 261 |  |  |  |  |  |  | # Returns: | 
| 262 |  |  |  |  |  |  | #   Anonymous hash of user info. | 
| 263 |  |  |  |  |  |  | sub me | 
| 264 |  |  |  |  |  |  | { | 
| 265 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 266 |  |  |  |  |  |  |  | 
| 267 | 0 |  |  |  |  |  | my $response = $self->_get("users"); | 
| 268 |  |  |  |  |  |  |  | 
| 269 | 0 |  |  |  |  |  | return $response; | 
| 270 |  |  |  |  |  |  | } | 
| 271 |  |  |  |  |  |  |  | 
| 272 |  |  |  |  |  |  | # Function: get_user | 
| 273 |  |  |  |  |  |  | # | 
| 274 |  |  |  |  |  |  | # Gets information about user specified by id. | 
| 275 |  |  |  |  |  |  | # | 
| 276 |  |  |  |  |  |  | # Parameters: | 
| 277 |  |  |  |  |  |  | #   self - object instance. | 
| 278 |  |  |  |  |  |  | #   id   - user id. | 
| 279 |  |  |  |  |  |  | # | 
| 280 |  |  |  |  |  |  | # Returns: | 
| 281 |  |  |  |  |  |  | #   Anonymous hash of user info. | 
| 282 |  |  |  |  |  |  | sub get_user | 
| 283 |  |  |  |  |  |  | { | 
| 284 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 285 | 0 |  |  |  |  |  | my $id   = shift; | 
| 286 |  |  |  |  |  |  |  | 
| 287 | 0 | 0 |  |  |  |  | if (!$self->is_id_valid($id)) { | 
| 288 |  |  |  |  |  |  | #$self->set_error("Please enter a valid Dwolla Id."); | 
| 289 |  |  |  |  |  |  | #return 0; | 
| 290 |  |  |  |  |  |  | } | 
| 291 |  |  |  |  |  |  |  | 
| 292 | 0 |  |  |  |  |  | my $params = { | 
| 293 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 294 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 295 |  |  |  |  |  |  | }; | 
| 296 |  |  |  |  |  |  |  | 
| 297 | 0 |  |  |  |  |  | my $response = $self->_get("users/$id",$params); | 
| 298 |  |  |  |  |  |  |  | 
| 299 | 0 |  |  |  |  |  | return $response; | 
| 300 |  |  |  |  |  |  | } | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | # Function: users_nearby | 
| 303 |  |  |  |  |  |  | # | 
| 304 |  |  |  |  |  |  | # Gets list of users given geo-coordinates. | 
| 305 |  |  |  |  |  |  | # | 
| 306 |  |  |  |  |  |  | # Parameters: | 
| 307 |  |  |  |  |  |  | #   self - Object instance. | 
| 308 |  |  |  |  |  |  | #   lat  - Latitude. | 
| 309 |  |  |  |  |  |  | #   long - Longitude. | 
| 310 |  |  |  |  |  |  | # | 
| 311 |  |  |  |  |  |  | # Returns: | 
| 312 |  |  |  |  |  |  | #   An array of anonymous hashes containing user info. | 
| 313 |  |  |  |  |  |  | sub users_nearby | 
| 314 |  |  |  |  |  |  | { | 
| 315 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 316 | 0 |  |  |  |  |  | my $lat  = shift; | 
| 317 | 0 |  |  |  |  |  | my $long = shift; | 
| 318 |  |  |  |  |  |  |  | 
| 319 | 0 |  |  |  |  |  | my $params = { | 
| 320 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 321 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 322 |  |  |  |  |  |  | 'latitude'      => $lat, | 
| 323 |  |  |  |  |  |  | 'longitude'     => $long | 
| 324 |  |  |  |  |  |  | }; | 
| 325 |  |  |  |  |  |  |  | 
| 326 | 0 |  |  |  |  |  | my $response = $self->_get("users/nearby",$params); | 
| 327 |  |  |  |  |  |  |  | 
| 328 | 0 |  |  |  |  |  | return $response; | 
| 329 |  |  |  |  |  |  | } | 
| 330 |  |  |  |  |  |  |  | 
| 331 |  |  |  |  |  |  | # Function: register | 
| 332 |  |  |  |  |  |  | # | 
| 333 |  |  |  |  |  |  | # Register a new Dwolla account. | 
| 334 |  |  |  |  |  |  | # | 
| 335 |  |  |  |  |  |  | # Parameters: | 
| 336 |  |  |  |  |  |  | #   self          - Object instance. | 
| 337 |  |  |  |  |  |  | #   email         - Email address. | 
| 338 |  |  |  |  |  |  | #   password      - Password. | 
| 339 |  |  |  |  |  |  | #   pin           - 4-digit Dwolla pin. | 
| 340 |  |  |  |  |  |  | #   first_name    - First name. | 
| 341 |  |  |  |  |  |  | #   last_name     - Last name. | 
| 342 |  |  |  |  |  |  | #   address       - Address line 1. | 
| 343 |  |  |  |  |  |  | #   address2      - Address line 2 (Optional) | 
| 344 |  |  |  |  |  |  | #   city          - City. | 
| 345 |  |  |  |  |  |  | #   state         - State. | 
| 346 |  |  |  |  |  |  | #   zip           - Zipcode. | 
| 347 |  |  |  |  |  |  | #   phone         - Phone number. | 
| 348 |  |  |  |  |  |  | #   date_of_birth - Date of birth. | 
| 349 |  |  |  |  |  |  | #   accept_terms  - Has the new user accepted the terms? | 
| 350 |  |  |  |  |  |  | #   type          - User type ('Personal',Commercial','NonProfit) | 
| 351 |  |  |  |  |  |  | #   organization  - Organization. | 
| 352 |  |  |  |  |  |  | #   ein           - Employee Identifer Number | 
| 353 |  |  |  |  |  |  | # | 
| 354 |  |  |  |  |  |  | # Returns: | 
| 355 |  |  |  |  |  |  | #   Registration response or false (0) for error. | 
| 356 |  |  |  |  |  |  | sub register | 
| 357 |  |  |  |  |  |  | { | 
| 358 | 0 |  |  | 0 | 0 |  | my $self          = shift; | 
| 359 | 0 |  |  |  |  |  | my $email         = shift; | 
| 360 | 0 |  |  |  |  |  | my $password      = shift; | 
| 361 | 0 |  |  |  |  |  | my $pin           = shift; | 
| 362 | 0 |  |  |  |  |  | my $first_name    = shift; | 
| 363 | 0 |  |  |  |  |  | my $last_name     = shift; | 
| 364 | 0 |  |  |  |  |  | my $address       = shift; | 
| 365 | 0 |  | 0 |  |  |  | my $address2      = shift || ''; | 
| 366 | 0 |  |  |  |  |  | my $city          = shift; | 
| 367 | 0 |  |  |  |  |  | my $state         = shift; | 
| 368 | 0 |  |  |  |  |  | my $zip           = shift; | 
| 369 | 0 |  |  |  |  |  | my $phone         = shift; | 
| 370 | 0 |  |  |  |  |  | my $date_of_birth = shift; | 
| 371 | 0 |  | 0 |  |  |  | my $accept_terms  = shift || 0; | 
| 372 | 0 |  | 0 |  |  |  | my $type          = shift || 'Personal'; | 
| 373 | 0 |  | 0 |  |  |  | my $organization  = shift || ''; | 
| 374 | 0 |  | 0 |  |  |  | my $ein           = shift || undef; | 
| 375 |  |  |  |  |  |  |  | 
| 376 | 0 |  |  |  |  |  | my $errors = 0; | 
| 377 |  |  |  |  |  |  |  | 
| 378 | 0 | 0 | 0 |  |  |  | if ($type ne 'Personal' && $type ne 'Commercial' && $type ne 'NonProfit') { | 
|  |  |  | 0 |  |  |  |  | 
| 379 | 0 |  |  |  |  |  | $self->set_error("Please enter a valid account type."); | 
| 380 | 0 |  |  |  |  |  | $errors++; | 
| 381 |  |  |  |  |  |  | } | 
| 382 |  |  |  |  |  |  |  | 
| 383 | 0 | 0 | 0 |  |  |  | if (!defined($date_of_birth) || $date_of_birth !~ /^\d{2}\-\d{2}\-\d{4}$/) { | 
| 384 | 0 |  |  |  |  |  | $self->set_error("Please enter a valid date of birth."); | 
| 385 | 0 |  |  |  |  |  | $errors++; | 
| 386 |  |  |  |  |  |  | } | 
| 387 |  |  |  |  |  |  |  | 
| 388 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 389 | 0 |  |  |  |  |  | return 0; | 
| 390 |  |  |  |  |  |  | } | 
| 391 |  |  |  |  |  |  |  | 
| 392 | 0 |  |  |  |  |  | my $params = { | 
| 393 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 394 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 395 |  |  |  |  |  |  | 'email'         => $email, | 
| 396 |  |  |  |  |  |  | 'password'      => $password, | 
| 397 |  |  |  |  |  |  | 'pin'           => $pin, | 
| 398 |  |  |  |  |  |  | 'firstName'     => $first_name, | 
| 399 |  |  |  |  |  |  | 'lastName'      => $last_name, | 
| 400 |  |  |  |  |  |  | 'address'       => $address, | 
| 401 |  |  |  |  |  |  | 'address2'      => $address2, | 
| 402 |  |  |  |  |  |  | 'city'          => $city, | 
| 403 |  |  |  |  |  |  | 'state'         => $state, | 
| 404 |  |  |  |  |  |  | 'zip'           => $zip, | 
| 405 |  |  |  |  |  |  | 'phone'         => $phone, | 
| 406 |  |  |  |  |  |  | 'dateOfBirth'   => $date_of_birth, | 
| 407 |  |  |  |  |  |  | 'type'          => $type, | 
| 408 |  |  |  |  |  |  | 'organization'  => $organization, | 
| 409 |  |  |  |  |  |  | 'ein'           => $ein, | 
| 410 |  |  |  |  |  |  | 'acceptTerms'   => $accept_terms | 
| 411 |  |  |  |  |  |  | }; | 
| 412 |  |  |  |  |  |  |  | 
| 413 | 0 |  |  |  |  |  | my $response = $self->_post("register/",$params,0); | 
| 414 |  |  |  |  |  |  |  | 
| 415 | 0 |  |  |  |  |  | return $response; | 
| 416 |  |  |  |  |  |  | } | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | # Function: contacts | 
| 419 |  |  |  |  |  |  | # | 
| 420 |  |  |  |  |  |  | # Get a list of contacts. | 
| 421 |  |  |  |  |  |  | # | 
| 422 |  |  |  |  |  |  | # Parameters: | 
| 423 |  |  |  |  |  |  | #   self   - Object instance. | 
| 424 |  |  |  |  |  |  | #   search - Search term. | 
| 425 |  |  |  |  |  |  | #   types  - Account types (e.g Dwolla, Facebook) Default: 'Dwolla'. | 
| 426 |  |  |  |  |  |  | #   limit  - Limit results. Default: 10. | 
| 427 |  |  |  |  |  |  | # | 
| 428 |  |  |  |  |  |  | # Returns: | 
| 429 |  |  |  |  |  |  | #   Array of contact information. | 
| 430 |  |  |  |  |  |  | sub contacts | 
| 431 |  |  |  |  |  |  | { | 
| 432 | 0 |  |  | 0 | 0 |  | my $self   = shift; | 
| 433 | 0 |  |  |  |  |  | my $search = shift; | 
| 434 | 0 |  | 0 |  |  |  | my $types  = shift || ['Dwolla']; | 
| 435 | 0 |  | 0 |  |  |  | my $limit  = shift || 10; | 
| 436 |  |  |  |  |  |  |  | 
| 437 | 0 |  |  |  |  |  | my $params = { | 
| 438 |  |  |  |  |  |  | 'search' => $self->{'api_key'}, | 
| 439 | 0 |  |  |  |  |  | 'types'  => join(',',@{$types}), | 
| 440 |  |  |  |  |  |  | 'limit'  => $limit | 
| 441 |  |  |  |  |  |  | }; | 
| 442 |  |  |  |  |  |  |  | 
| 443 | 0 |  |  |  |  |  | my $response = $self->_get("contacts",$params); | 
| 444 |  |  |  |  |  |  |  | 
| 445 | 0 |  |  |  |  |  | return $response; | 
| 446 |  |  |  |  |  |  | } | 
| 447 |  |  |  |  |  |  |  | 
| 448 |  |  |  |  |  |  | # Function: nearby_contacts | 
| 449 |  |  |  |  |  |  | # | 
| 450 |  |  |  |  |  |  | # Gets list of nearby Dwolla spots withing the range of the provided | 
| 451 |  |  |  |  |  |  | # latitude and longitude. | 
| 452 |  |  |  |  |  |  | # | 
| 453 |  |  |  |  |  |  | # Half of the limit are returned as spots with closest proximity. The other | 
| 454 |  |  |  |  |  |  | # half of the spots are returned as random spots within the range. | 
| 455 |  |  |  |  |  |  | # This call can return nearby venues on Foursquare but not Dwolla, they will | 
| 456 |  |  |  |  |  |  | # have an Id of "null" | 
| 457 |  |  |  |  |  |  | # | 
| 458 |  |  |  |  |  |  | # Parameters: | 
| 459 |  |  |  |  |  |  | #   self  - object instance. | 
| 460 |  |  |  |  |  |  | #   lat   - Latitude. | 
| 461 |  |  |  |  |  |  | #   long  - Longitude. | 
| 462 |  |  |  |  |  |  | #   range - Range to search (miles). | 
| 463 |  |  |  |  |  |  | #   limit - Limit results to this number. | 
| 464 |  |  |  |  |  |  | # | 
| 465 |  |  |  |  |  |  | # Returns: | 
| 466 |  |  |  |  |  |  | #   Array of anonymous hashes containing contacts. | 
| 467 |  |  |  |  |  |  | sub nearby_contacts | 
| 468 |  |  |  |  |  |  | { | 
| 469 | 0 |  |  | 0 | 0 |  | my $self  = shift; | 
| 470 | 0 |  |  |  |  |  | my $lat   = shift; | 
| 471 | 0 |  |  |  |  |  | my $long  = shift; | 
| 472 | 0 |  | 0 |  |  |  | my $range = shift || 10; | 
| 473 | 0 |  | 0 |  |  |  | my $limit = shift || 10; | 
| 474 |  |  |  |  |  |  |  | 
| 475 | 0 |  |  |  |  |  | my $params = { | 
| 476 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 477 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 478 |  |  |  |  |  |  | 'latitude'      => $lat, | 
| 479 |  |  |  |  |  |  | 'longitude'     => $long, | 
| 480 |  |  |  |  |  |  | 'range'         => $range, | 
| 481 |  |  |  |  |  |  | 'limit'         => $limit | 
| 482 |  |  |  |  |  |  | }; | 
| 483 |  |  |  |  |  |  |  | 
| 484 | 0 |  |  |  |  |  | my $response = $self->_get("contacts/nearby",$params); | 
| 485 |  |  |  |  |  |  |  | 
| 486 | 0 |  |  |  |  |  | return $response; | 
| 487 |  |  |  |  |  |  | } | 
| 488 |  |  |  |  |  |  |  | 
| 489 |  |  |  |  |  |  | # Function: funding_sources | 
| 490 |  |  |  |  |  |  | # | 
| 491 |  |  |  |  |  |  | # Retrieve a list of verified funding sources for the user associated | 
| 492 |  |  |  |  |  |  | # with the authorized access token. | 
| 493 |  |  |  |  |  |  | # | 
| 494 |  |  |  |  |  |  | # Paramters: | 
| 495 |  |  |  |  |  |  | #   self     - Object instance. | 
| 496 |  |  |  |  |  |  | # | 
| 497 |  |  |  |  |  |  | # Returns: | 
| 498 |  |  |  |  |  |  | #   Array of anonymous hashes containg funding sources. | 
| 499 |  |  |  |  |  |  | sub funding_sources | 
| 500 |  |  |  |  |  |  | { | 
| 501 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 502 |  |  |  |  |  |  |  | 
| 503 | 0 |  |  |  |  |  | my $response = $self->_get("fundingsources"); | 
| 504 |  |  |  |  |  |  |  | 
| 505 | 0 |  |  |  |  |  | return $response; | 
| 506 |  |  |  |  |  |  | } | 
| 507 |  |  |  |  |  |  |  | 
| 508 |  |  |  |  |  |  | # Function: funding_source | 
| 509 |  |  |  |  |  |  | # | 
| 510 |  |  |  |  |  |  | # Retrieve a funding source given its id. | 
| 511 |  |  |  |  |  |  | # | 
| 512 |  |  |  |  |  |  | # Paramters: | 
| 513 |  |  |  |  |  |  | #   self     - Object instance. | 
| 514 |  |  |  |  |  |  | #   sourceid - Fund source id. | 
| 515 |  |  |  |  |  |  | # | 
| 516 |  |  |  |  |  |  | # Returns: | 
| 517 |  |  |  |  |  |  | #   Anonymous hash containg funding sources. | 
| 518 |  |  |  |  |  |  | sub funding_source | 
| 519 |  |  |  |  |  |  | { | 
| 520 | 0 |  |  | 0 | 0 |  | my $self     = shift; | 
| 521 | 0 |  |  |  |  |  | my $sourceid = shift; | 
| 522 |  |  |  |  |  |  |  | 
| 523 | 0 |  |  |  |  |  | my $response = $self->_get("fundingsources/$sourceid"); | 
| 524 |  |  |  |  |  |  |  | 
| 525 | 0 |  |  |  |  |  | return $response; | 
| 526 |  |  |  |  |  |  | } | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | # Function: add_funding_source | 
| 529 |  |  |  |  |  |  | # | 
| 530 |  |  |  |  |  |  | # Add a new funding source for the user associated with the | 
| 531 |  |  |  |  |  |  | # authorized access token. | 
| 532 |  |  |  |  |  |  | # | 
| 533 |  |  |  |  |  |  | # Parameters: | 
| 534 |  |  |  |  |  |  | #   self     - Object instance. | 
| 535 |  |  |  |  |  |  | #   acctnum  - Financial institution account number. | 
| 536 |  |  |  |  |  |  | #   trnnum   - Routing number. | 
| 537 |  |  |  |  |  |  | #   accttype - Account type ('checking','savings') | 
| 538 |  |  |  |  |  |  | #   acctname - Name to give account. | 
| 539 |  |  |  |  |  |  | # | 
| 540 |  |  |  |  |  |  | # Returns: | 
| 541 |  |  |  |  |  |  | #   Funding sources. | 
| 542 |  |  |  |  |  |  | sub add_funding_source | 
| 543 |  |  |  |  |  |  | { | 
| 544 | 0 |  |  | 0 | 0 |  | my $self     = shift; | 
| 545 | 0 |  | 0 |  |  |  | my $acctnum  = shift || undef; | 
| 546 | 0 |  | 0 |  |  |  | my $trnnum   = shift || undef; | 
| 547 | 0 |  | 0 |  |  |  | my $accttype = shift || undef; | 
| 548 | 0 |  | 0 |  |  |  | my $acctname = shift || undef; | 
| 549 |  |  |  |  |  |  |  | 
| 550 | 0 |  |  |  |  |  | my $errors = 0; | 
| 551 |  |  |  |  |  |  |  | 
| 552 | 0 | 0 |  |  |  |  | if (!defined($acctnum)) { | 
| 553 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid account number.'); | 
| 554 | 0 |  |  |  |  |  | $errors++; | 
| 555 |  |  |  |  |  |  | } | 
| 556 | 0 | 0 | 0 |  |  |  | if (!defined($trnnum) || $trnnum !~ /^[0-9]{9}$/) { | 
| 557 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid routing number.'); | 
| 558 | 0 |  |  |  |  |  | $errors++; | 
| 559 |  |  |  |  |  |  | } | 
| 560 |  |  |  |  |  |  |  | 
| 561 | 0 | 0 | 0 |  |  |  | if (!defined($accttype) || ($accttype ne 'Checking' && $accttype ne 'Savings')) { | 
|  |  |  | 0 |  |  |  |  | 
| 562 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid account type.'); | 
| 563 | 0 |  |  |  |  |  | $errors++; | 
| 564 |  |  |  |  |  |  | } | 
| 565 |  |  |  |  |  |  |  | 
| 566 | 0 | 0 |  |  |  |  | if (!defined($acctname)) { | 
| 567 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid account name.'); | 
| 568 | 0 |  |  |  |  |  | $errors++; | 
| 569 |  |  |  |  |  |  | } | 
| 570 |  |  |  |  |  |  |  | 
| 571 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 572 | 0 |  |  |  |  |  | return 0; | 
| 573 |  |  |  |  |  |  | } | 
| 574 |  |  |  |  |  |  |  | 
| 575 | 0 |  |  |  |  |  | my $params = { | 
| 576 |  |  |  |  |  |  | 'account_number' => $acctnum, | 
| 577 |  |  |  |  |  |  | 'routing_number' => $trnnum, | 
| 578 |  |  |  |  |  |  | 'account_type'   => $accttype, | 
| 579 |  |  |  |  |  |  | 'name'           => $acctname | 
| 580 |  |  |  |  |  |  | }; | 
| 581 |  |  |  |  |  |  |  | 
| 582 | 0 |  |  |  |  |  | my $response = $self->_post("fundingsources/",$params); | 
| 583 |  |  |  |  |  |  |  | 
| 584 | 0 |  |  |  |  |  | return $response; | 
| 585 |  |  |  |  |  |  | } | 
| 586 |  |  |  |  |  |  |  | 
| 587 |  |  |  |  |  |  | # Function: verify_funding_source | 
| 588 |  |  |  |  |  |  | # | 
| 589 |  |  |  |  |  |  | # Verify a funding source. | 
| 590 |  |  |  |  |  |  | # | 
| 591 |  |  |  |  |  |  | # Parameters: | 
| 592 |  |  |  |  |  |  | #   self               - Object instance. | 
| 593 |  |  |  |  |  |  | #   sourceid           - Fund source Id. | 
| 594 |  |  |  |  |  |  | #   deposit1           - Verification deposit amount 1. | 
| 595 |  |  |  |  |  |  | #   deposit2           - Verification deposit amount 2. | 
| 596 |  |  |  |  |  |  | # | 
| 597 |  |  |  |  |  |  | # Returns: | 
| 598 |  |  |  |  |  |  | #   Request Id or array or false (0) on error. | 
| 599 |  |  |  |  |  |  | sub verify_funding_source | 
| 600 |  |  |  |  |  |  | { | 
| 601 | 0 |  |  | 0 | 0 |  | my $self     = shift; | 
| 602 | 0 |  | 0 |  |  |  | my $sourceid = shift || undef; | 
| 603 | 0 |  | 0 |  |  |  | my $deposit1 = shift || undef; | 
| 604 | 0 |  | 0 |  |  |  | my $deposit2 = shift || undef; | 
| 605 |  |  |  |  |  |  |  | 
| 606 | 0 |  |  |  |  |  | my $errors = 0; | 
| 607 |  |  |  |  |  |  |  | 
| 608 | 0 | 0 |  |  |  |  | if (!defined($sourceid)) { | 
| 609 | 0 |  |  |  |  |  | $self->set_error("Please provide a valid funding source."); | 
| 610 | 0 |  |  |  |  |  | $errors++; | 
| 611 |  |  |  |  |  |  | } | 
| 612 |  |  |  |  |  |  |  | 
| 613 | 0 | 0 |  |  |  |  | if (!defined($deposit1)) { | 
| 614 | 0 |  |  |  |  |  | $self->set_error("Please provide deposit #1."); | 
| 615 | 0 |  |  |  |  |  | $errors++; | 
| 616 |  |  |  |  |  |  | } | 
| 617 |  |  |  |  |  |  |  | 
| 618 | 0 | 0 |  |  |  |  | if (!defined($deposit2)) { | 
| 619 | 0 |  |  |  |  |  | $self->set_error("Please provide deposit #2."); | 
| 620 | 0 |  |  |  |  |  | $errors++; | 
| 621 |  |  |  |  |  |  | } | 
| 622 |  |  |  |  |  |  |  | 
| 623 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 624 | 0 |  |  |  |  |  | return 0; | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  |  | 
| 627 | 0 |  |  |  |  |  | my $params = { | 
| 628 |  |  |  |  |  |  | 'deposit1' => $deposit1, | 
| 629 |  |  |  |  |  |  | 'deposit2' => $deposit2 | 
| 630 |  |  |  |  |  |  | }; | 
| 631 |  |  |  |  |  |  |  | 
| 632 | 0 |  |  |  |  |  | my $response = $self->_post("fundingsources/$sourceid/verify",$params); | 
| 633 |  |  |  |  |  |  |  | 
| 634 | 0 |  |  |  |  |  | return $response; | 
| 635 |  |  |  |  |  |  | } | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | # Function: withdraw | 
| 638 |  |  |  |  |  |  | # | 
| 639 |  |  |  |  |  |  | # Withdraw money from a funding source. | 
| 640 |  |  |  |  |  |  | # | 
| 641 |  |  |  |  |  |  | # Parameters: | 
| 642 |  |  |  |  |  |  | #   self      - Object instance. | 
| 643 |  |  |  |  |  |  | #   sourceid  - Fund source Id. | 
| 644 |  |  |  |  |  |  | #   pin       - Dwolla pin. | 
| 645 |  |  |  |  |  |  | #   amount    - Deposit amount. | 
| 646 |  |  |  |  |  |  | # | 
| 647 |  |  |  |  |  |  | # Returns: | 
| 648 |  |  |  |  |  |  | #   Response or 0 on error. | 
| 649 |  |  |  |  |  |  | sub withdraw | 
| 650 |  |  |  |  |  |  | { | 
| 651 | 0 |  |  | 0 | 0 |  | my $self     = shift; | 
| 652 | 0 |  | 0 |  |  |  | my $sourceid = shift || undef; | 
| 653 | 0 |  | 0 |  |  |  | my $pin      = shift || undef; | 
| 654 | 0 |  | 0 |  |  |  | my $amount   = shift || undef; | 
| 655 |  |  |  |  |  |  |  | 
| 656 | 0 |  |  |  |  |  | my $errors = 0; | 
| 657 |  |  |  |  |  |  |  | 
| 658 | 0 | 0 | 0 |  |  |  | if (!defined($pin) || $pin !~ /^[0-9]{4}$/) { | 
| 659 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid pin.'); | 
| 660 | 0 |  |  |  |  |  | $errors++; | 
| 661 |  |  |  |  |  |  | } | 
| 662 |  |  |  |  |  |  |  | 
| 663 | 0 | 0 |  |  |  |  | if (!defined($sourceid)) { | 
| 664 | 0 |  |  |  |  |  | $self->set_error('Please supply a fund source.'); | 
| 665 | 0 |  |  |  |  |  | $errors++; | 
| 666 |  |  |  |  |  |  | } | 
| 667 |  |  |  |  |  |  |  | 
| 668 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 669 | 0 |  |  |  |  |  | $self->set_error('Please supply an amount.'); | 
| 670 | 0 |  |  |  |  |  | $errors++; | 
| 671 |  |  |  |  |  |  | } | 
| 672 |  |  |  |  |  |  |  | 
| 673 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 674 | 0 |  |  |  |  |  | return 0; | 
| 675 |  |  |  |  |  |  | } | 
| 676 |  |  |  |  |  |  |  | 
| 677 | 0 |  |  |  |  |  | my $params = { | 
| 678 |  |  |  |  |  |  | 'pin'    => $pin, | 
| 679 |  |  |  |  |  |  | 'amount' => $amount | 
| 680 |  |  |  |  |  |  | }; | 
| 681 |  |  |  |  |  |  |  | 
| 682 | 0 |  |  |  |  |  | my $response = $self->_post("fundingsources/$sourceid/withdraw",$params); | 
| 683 |  |  |  |  |  |  |  | 
| 684 | 0 |  |  |  |  |  | return $response; | 
| 685 |  |  |  |  |  |  | } | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | # Function: deposit | 
| 688 |  |  |  |  |  |  | # | 
| 689 |  |  |  |  |  |  | # Deposit money into a funding source. | 
| 690 |  |  |  |  |  |  | # | 
| 691 |  |  |  |  |  |  | # Parameters: | 
| 692 |  |  |  |  |  |  | #   sourceid  - Fund source Id. | 
| 693 |  |  |  |  |  |  | #   pin       - Dwolla pin. | 
| 694 |  |  |  |  |  |  | #   amount    - Deposit amount. | 
| 695 |  |  |  |  |  |  | # | 
| 696 |  |  |  |  |  |  | # Returns: | 
| 697 |  |  |  |  |  |  | #   Response or 0 on error. | 
| 698 |  |  |  |  |  |  | sub deposit | 
| 699 |  |  |  |  |  |  | { | 
| 700 | 0 |  |  | 0 | 0 |  | my $self     = shift; | 
| 701 | 0 |  | 0 |  |  |  | my $sourceid = shift || undef; | 
| 702 | 0 |  | 0 |  |  |  | my $pin      = shift || undef; | 
| 703 | 0 |  | 0 |  |  |  | my $amount   = shift || undef; | 
| 704 |  |  |  |  |  |  |  | 
| 705 | 0 |  |  |  |  |  | my $errors = 0; | 
| 706 |  |  |  |  |  |  |  | 
| 707 | 0 | 0 | 0 |  |  |  | if (!defined($pin) || $pin !~ /^[0-9]{4}$/) { | 
| 708 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid pin.'); | 
| 709 | 0 |  |  |  |  |  | $errors++; | 
| 710 |  |  |  |  |  |  | } | 
| 711 |  |  |  |  |  |  |  | 
| 712 | 0 | 0 |  |  |  |  | if (!defined($sourceid)) { | 
| 713 | 0 |  |  |  |  |  | $self->set_error('Please supply a fund source.'); | 
| 714 | 0 |  |  |  |  |  | $errors++; | 
| 715 |  |  |  |  |  |  | } | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 718 | 0 |  |  |  |  |  | $self->set_error('Please supply an amount'); | 
| 719 | 0 |  |  |  |  |  | $errors++; | 
| 720 |  |  |  |  |  |  | } | 
| 721 |  |  |  |  |  |  |  | 
| 722 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 723 | 0 |  |  |  |  |  | return 0; | 
| 724 |  |  |  |  |  |  | } | 
| 725 |  |  |  |  |  |  |  | 
| 726 | 0 |  |  |  |  |  | my $params = { | 
| 727 |  |  |  |  |  |  | 'pin'    => $pin, | 
| 728 |  |  |  |  |  |  | 'amount' => $amount | 
| 729 |  |  |  |  |  |  | }; | 
| 730 |  |  |  |  |  |  |  | 
| 731 | 0 |  |  |  |  |  | my $response = $self->_post("fundingsources/$sourceid/deposit",$params); | 
| 732 |  |  |  |  |  |  |  | 
| 733 | 0 |  |  |  |  |  | return $response; | 
| 734 |  |  |  |  |  |  | } | 
| 735 |  |  |  |  |  |  |  | 
| 736 |  |  |  |  |  |  | # Function: balance | 
| 737 |  |  |  |  |  |  | # | 
| 738 |  |  |  |  |  |  | # Retrieve the account balance for the user with the given authorized | 
| 739 |  |  |  |  |  |  | # access token. | 
| 740 |  |  |  |  |  |  | # | 
| 741 |  |  |  |  |  |  | # Parameters: | 
| 742 |  |  |  |  |  |  | #   self - Object instance. | 
| 743 |  |  |  |  |  |  | # | 
| 744 |  |  |  |  |  |  | # Returns: | 
| 745 |  |  |  |  |  |  | #   Balance | 
| 746 |  |  |  |  |  |  | sub balance | 
| 747 |  |  |  |  |  |  | { | 
| 748 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 749 |  |  |  |  |  |  |  | 
| 750 | 0 |  |  |  |  |  | my $response = $self->_get("balance"); | 
| 751 |  |  |  |  |  |  |  | 
| 752 | 0 |  |  |  |  |  | return $response; | 
| 753 |  |  |  |  |  |  | } | 
| 754 |  |  |  |  |  |  |  | 
| 755 |  |  |  |  |  |  | # Function: send | 
| 756 |  |  |  |  |  |  | # | 
| 757 |  |  |  |  |  |  | # Send funds to a user, originating from the user associated | 
| 758 |  |  |  |  |  |  | # with the authorized access token. | 
| 759 |  |  |  |  |  |  | # | 
| 760 |  |  |  |  |  |  | # Parameters: | 
| 761 |  |  |  |  |  |  | #   self               - Object instance. | 
| 762 |  |  |  |  |  |  | #   pin                - Dwolla pin. | 
| 763 |  |  |  |  |  |  | #   destid             - Destination Id. | 
| 764 |  |  |  |  |  |  | #   amount             - Transaction amount. | 
| 765 |  |  |  |  |  |  | #   dtype              - Destination type. | 
| 766 |  |  |  |  |  |  | #   notes              - Transaction notes.. | 
| 767 |  |  |  |  |  |  | #   facilitator_amount - Faciltitator amount. | 
| 768 |  |  |  |  |  |  | #   assume_costs       - Assume Dwolla costs? | 
| 769 |  |  |  |  |  |  | #   fund_source        - Fund source. Default: 'balance' | 
| 770 |  |  |  |  |  |  | # | 
| 771 |  |  |  |  |  |  | # Returns: | 
| 772 |  |  |  |  |  |  | #   Request Id or array or false on error. | 
| 773 |  |  |  |  |  |  | sub send | 
| 774 |  |  |  |  |  |  | { | 
| 775 | 0 |  |  | 0 | 0 |  | my $self               = shift; | 
| 776 | 0 |  | 0 |  |  |  | my $pin                = shift || undef; | 
| 777 | 0 |  | 0 |  |  |  | my $destid             = shift || undef; | 
| 778 | 0 |  | 0 |  |  |  | my $amount             = shift || undef; | 
| 779 | 0 |  | 0 |  |  |  | my $dtype              = shift || 'Dwolla'; | 
| 780 | 0 |  | 0 |  |  |  | my $notes              = shift || ''; | 
| 781 | 0 |  | 0 |  |  |  | my $facilitator_amount = shift || 0; | 
| 782 | 0 |  | 0 |  |  |  | my $assume_costs       = shift || 0; | 
| 783 | 0 |  | 0 |  |  |  | my $fund_source        = shift || 'balance'; | 
| 784 |  |  |  |  |  |  |  | 
| 785 | 0 |  |  |  |  |  | my $errors = 0; | 
| 786 |  |  |  |  |  |  |  | 
| 787 | 0 | 0 | 0 |  |  |  | if (!defined($pin) || $pin !~ /^[0-9]+$/) { | 
| 788 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid pin.'); | 
| 789 | 0 |  |  |  |  |  | $errors++; | 
| 790 |  |  |  |  |  |  | } | 
| 791 |  |  |  |  |  |  |  | 
| 792 | 0 | 0 |  |  |  |  | if (!defined($destid)) { | 
| 793 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid destination.'); | 
| 794 | 0 |  |  |  |  |  | $errors++; | 
| 795 |  |  |  |  |  |  | } | 
| 796 |  |  |  |  |  |  |  | 
| 797 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 798 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid amount.'); | 
| 799 | 0 |  |  |  |  |  | $errors++; | 
| 800 |  |  |  |  |  |  | } | 
| 801 |  |  |  |  |  |  |  | 
| 802 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 803 | 0 |  |  |  |  |  | return 0; | 
| 804 |  |  |  |  |  |  | } | 
| 805 |  |  |  |  |  |  |  | 
| 806 | 0 |  |  |  |  |  | my $params = { | 
| 807 |  |  |  |  |  |  | 'pin'               => $pin, | 
| 808 |  |  |  |  |  |  | 'destinationId'     => $destid, | 
| 809 |  |  |  |  |  |  | 'destinationType'   => $dtype, | 
| 810 |  |  |  |  |  |  | 'amount'            => $amount, | 
| 811 |  |  |  |  |  |  | 'facilitatorAmount' => $facilitator_amount, | 
| 812 |  |  |  |  |  |  | 'assumeCosts'       => $assume_costs, | 
| 813 |  |  |  |  |  |  | 'notes'             => $notes, | 
| 814 |  |  |  |  |  |  | 'fundsSource'       => $fund_source | 
| 815 |  |  |  |  |  |  | }; | 
| 816 |  |  |  |  |  |  |  | 
| 817 | 0 |  |  |  |  |  | my $response = $self->_post("transactions/send",$params); | 
| 818 |  |  |  |  |  |  |  | 
| 819 | 0 |  |  |  |  |  | return $response; | 
| 820 |  |  |  |  |  |  | } | 
| 821 |  |  |  |  |  |  |  | 
| 822 |  |  |  |  |  |  | # Function: guest_send | 
| 823 |  |  |  |  |  |  | # | 
| 824 |  |  |  |  |  |  | # Send funds to a destination user, from a non-Dwolla user's bank account. | 
| 825 |  |  |  |  |  |  | # | 
| 826 |  |  |  |  |  |  | # Parameters: | 
| 827 |  |  |  |  |  |  | #   self         - Object instance. | 
| 828 |  |  |  |  |  |  | #   destid       - Destination Id. | 
| 829 |  |  |  |  |  |  | #   amount       - Transaction amount. | 
| 830 |  |  |  |  |  |  | #   first_name   - First Name. | 
| 831 |  |  |  |  |  |  | #   last_name    - Last name. | 
| 832 |  |  |  |  |  |  | #   email        - Email address. | 
| 833 |  |  |  |  |  |  | #   trnnum       - Transit routing number. | 
| 834 |  |  |  |  |  |  | #   acctnum      - Account number. | 
| 835 |  |  |  |  |  |  | #   accttype     - Account type ('Checking','Savings') | 
| 836 |  |  |  |  |  |  | #   assume_costs - Assume Dwolla costs? | 
| 837 |  |  |  |  |  |  | #   dtype        - Destination type. | 
| 838 |  |  |  |  |  |  | #   notes        - Transaction Id. | 
| 839 |  |  |  |  |  |  | #   group_id     - ID specified by the client application. | 
| 840 |  |  |  |  |  |  | #   addtl_fees   - Additional faciliator fees (Array of anonymous hashes) | 
| 841 |  |  |  |  |  |  | # | 
| 842 |  |  |  |  |  |  | # Returns: | 
| 843 |  |  |  |  |  |  | #  Transaction info or false (0) on error | 
| 844 |  |  |  |  |  |  | sub guest_send | 
| 845 |  |  |  |  |  |  | { | 
| 846 | 0 |  |  | 0 | 0 |  | my $self         = shift; | 
| 847 | 0 |  |  |  |  |  | my $destid       = shift; | 
| 848 | 0 |  |  |  |  |  | my $amount       = shift; | 
| 849 | 0 |  |  |  |  |  | my $first_name   = shift; | 
| 850 | 0 |  |  |  |  |  | my $last_name    = shift; | 
| 851 | 0 |  |  |  |  |  | my $email        = shift; | 
| 852 | 0 |  |  |  |  |  | my $trnnum       = shift; | 
| 853 | 0 |  |  |  |  |  | my $acctnum      = shift; | 
| 854 | 0 |  |  |  |  |  | my $accttype     = shift; | 
| 855 | 0 |  | 0 |  |  |  | my $assume_costs = shift || 0; | 
| 856 | 0 |  | 0 |  |  |  | my $dtype        = shift || 'Dwolla'; | 
| 857 | 0 |  | 0 |  |  |  | my $notes        = shift || ''; | 
| 858 | 0 |  | 0 |  |  |  | my $group_id     = shift || undef; | 
| 859 | 0 |  | 0 |  |  |  | my $addtl_fees   = shift || undef; | 
| 860 |  |  |  |  |  |  |  | 
| 861 | 0 |  |  |  |  |  | my $errors = 0; | 
| 862 |  |  |  |  |  |  |  | 
| 863 | 0 | 0 |  |  |  |  | if (!defined($destid)) { | 
| 864 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid destination.'); | 
| 865 | 0 |  |  |  |  |  | $errors++; | 
| 866 |  |  |  |  |  |  | } | 
| 867 |  |  |  |  |  |  |  | 
| 868 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 869 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid amount.'); | 
| 870 | 0 |  |  |  |  |  | $errors++; | 
| 871 |  |  |  |  |  |  | } | 
| 872 |  |  |  |  |  |  |  | 
| 873 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 874 | 0 |  |  |  |  |  | return 0; | 
| 875 |  |  |  |  |  |  | } | 
| 876 |  |  |  |  |  |  |  | 
| 877 | 0 |  |  |  |  |  | my $params = { | 
| 878 |  |  |  |  |  |  | 'client_id'       => $self->{'api_key'}, | 
| 879 |  |  |  |  |  |  | 'client_secret'   => $self->{'api_secret'}, | 
| 880 |  |  |  |  |  |  | 'destinationId'   => $destid, | 
| 881 |  |  |  |  |  |  | 'destinationType' => $dtype, | 
| 882 |  |  |  |  |  |  | 'amount'          => $amount, | 
| 883 |  |  |  |  |  |  | 'emailAddress'    => $email, | 
| 884 |  |  |  |  |  |  | 'accountNumber'   => $acctnum, | 
| 885 |  |  |  |  |  |  | 'routingNumber'   => $trnnum, | 
| 886 |  |  |  |  |  |  | 'accountType'     => $accttype, | 
| 887 |  |  |  |  |  |  | 'firstName'       => $first_name, | 
| 888 |  |  |  |  |  |  | 'lastName'        => $last_name, | 
| 889 |  |  |  |  |  |  | 'assumeCosts'     => $assume_costs, | 
| 890 |  |  |  |  |  |  | 'notes'           => $notes, | 
| 891 |  |  |  |  |  |  | 'groupId'         => $group_id, | 
| 892 |  |  |  |  |  |  | 'additionalFees'  => $addtl_fees | 
| 893 |  |  |  |  |  |  | }; | 
| 894 |  |  |  |  |  |  |  | 
| 895 | 0 |  |  |  |  |  | my $response = $self->_post("transactions/guestsend",$params); | 
| 896 |  |  |  |  |  |  |  | 
| 897 | 0 |  |  |  |  |  | return $response; | 
| 898 |  |  |  |  |  |  | } | 
| 899 |  |  |  |  |  |  |  | 
| 900 |  |  |  |  |  |  | # Function: request | 
| 901 |  |  |  |  |  |  | # | 
| 902 |  |  |  |  |  |  | # Request funds from a source user, originating from the user associated | 
| 903 |  |  |  |  |  |  | # with the authorized access token. | 
| 904 |  |  |  |  |  |  | # | 
| 905 |  |  |  |  |  |  | # Parameters: | 
| 906 |  |  |  |  |  |  | #   self               - Object instance. | 
| 907 |  |  |  |  |  |  | #   sourceid           - Fund source Id. | 
| 908 |  |  |  |  |  |  | #   amount             - Transaction amount. | 
| 909 |  |  |  |  |  |  | #   stype              - Source type. | 
| 910 |  |  |  |  |  |  | #   notes              - Transaction Id. | 
| 911 |  |  |  |  |  |  | #   facilitator_amount - Faciltitator amount. | 
| 912 |  |  |  |  |  |  | # | 
| 913 |  |  |  |  |  |  | # Returns: | 
| 914 |  |  |  |  |  |  | #   Request Id or array or false on error. | 
| 915 |  |  |  |  |  |  | sub request | 
| 916 |  |  |  |  |  |  | { | 
| 917 | 0 |  |  | 0 | 0 |  | my $self               = shift; | 
| 918 | 0 |  | 0 |  |  |  | my $sourceid           = shift || undef; | 
| 919 | 0 |  | 0 |  |  |  | my $amount             = shift || undef; | 
| 920 | 0 |  | 0 |  |  |  | my $stype              = shift || 'Dwolla'; | 
| 921 | 0 |  | 0 |  |  |  | my $notes              = shift || ''; | 
| 922 | 0 |  | 0 |  |  |  | my $facilitator_amount = shift || 0; | 
| 923 |  |  |  |  |  |  |  | 
| 924 | 0 |  |  |  |  |  | my $errors = 0; | 
| 925 |  |  |  |  |  |  |  | 
| 926 | 0 | 0 |  |  |  |  | if (!defined($sourceid)) { | 
| 927 | 0 |  |  |  |  |  | $self->set_error('Please supply a fund source.'); | 
| 928 | 0 |  |  |  |  |  | $errors++; | 
| 929 |  |  |  |  |  |  | } | 
| 930 |  |  |  |  |  |  |  | 
| 931 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 932 | 0 |  |  |  |  |  | $self->set_error('Please supply a valid amount.'); | 
| 933 | 0 |  |  |  |  |  | $errors++; | 
| 934 |  |  |  |  |  |  | } | 
| 935 |  |  |  |  |  |  |  | 
| 936 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 937 | 0 |  |  |  |  |  | return 0; | 
| 938 |  |  |  |  |  |  | } | 
| 939 |  |  |  |  |  |  |  | 
| 940 | 0 |  |  |  |  |  | my $params = { | 
| 941 |  |  |  |  |  |  | 'sourceId'          => $sourceid, | 
| 942 |  |  |  |  |  |  | 'sourceType'        => $stype, | 
| 943 |  |  |  |  |  |  | 'amount'            => $amount, | 
| 944 |  |  |  |  |  |  | 'facilitatorAmount' => $facilitator_amount, | 
| 945 |  |  |  |  |  |  | 'notes'             => $notes | 
| 946 |  |  |  |  |  |  | }; | 
| 947 |  |  |  |  |  |  |  | 
| 948 | 0 |  |  |  |  |  | my $response = $self->_post("requests/",$params); | 
| 949 |  |  |  |  |  |  |  | 
| 950 | 0 |  |  |  |  |  | return $response; | 
| 951 |  |  |  |  |  |  | } | 
| 952 |  |  |  |  |  |  |  | 
| 953 |  |  |  |  |  |  | # Function: request_by_id | 
| 954 |  |  |  |  |  |  | # | 
| 955 |  |  |  |  |  |  | # Get a request by its id. | 
| 956 |  |  |  |  |  |  | # | 
| 957 |  |  |  |  |  |  | # Parameters: | 
| 958 |  |  |  |  |  |  | #   self - Object instance. | 
| 959 |  |  |  |  |  |  | #   id   - Request Id. | 
| 960 |  |  |  |  |  |  | # | 
| 961 |  |  |  |  |  |  | # Returns: | 
| 962 |  |  |  |  |  |  | #   Request information. | 
| 963 |  |  |  |  |  |  | sub request_by_id | 
| 964 |  |  |  |  |  |  | { | 
| 965 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 966 | 0 |  |  |  |  |  | my $id   = shift; | 
| 967 |  |  |  |  |  |  |  | 
| 968 | 0 |  |  |  |  |  | my $response = $self->_get("requests/$id"); | 
| 969 |  |  |  |  |  |  |  | 
| 970 | 0 |  |  |  |  |  | return $response; | 
| 971 |  |  |  |  |  |  | } | 
| 972 |  |  |  |  |  |  |  | 
| 973 |  |  |  |  |  |  | # Function: fulfill_request | 
| 974 |  |  |  |  |  |  | # | 
| 975 |  |  |  |  |  |  | # Fulfill a pending money request. | 
| 976 |  |  |  |  |  |  | # | 
| 977 |  |  |  |  |  |  | # Parameters: | 
| 978 |  |  |  |  |  |  | # | 
| 979 |  |  |  |  |  |  | #   self         - Object instance. | 
| 980 |  |  |  |  |  |  | #   id           - Request Id. | 
| 981 |  |  |  |  |  |  | #   pin          - Dwolla pin. | 
| 982 |  |  |  |  |  |  | #   amount       - Amount of transaction. | 
| 983 |  |  |  |  |  |  | #   notes        - Notes about transaction. | 
| 984 |  |  |  |  |  |  | #   fund_source  - Fund source. Default: 'balance' | 
| 985 |  |  |  |  |  |  | #   assume_costs - Assume transation cost? | 
| 986 |  |  |  |  |  |  | # | 
| 987 |  |  |  |  |  |  | # Returns: | 
| 988 |  |  |  |  |  |  | #   Transaction information. | 
| 989 |  |  |  |  |  |  | sub fulfill_request | 
| 990 |  |  |  |  |  |  | { | 
| 991 | 0 |  |  | 0 | 0 |  | my $self         = shift; | 
| 992 | 0 |  | 0 |  |  |  | my $id           = shift || undef; | 
| 993 | 0 |  | 0 |  |  |  | my $pin          = shift || undef; | 
| 994 | 0 |  | 0 |  |  |  | my $amount       = shift || undef; | 
| 995 | 0 |  | 0 |  |  |  | my $notes        = shift || ''; | 
| 996 | 0 |  | 0 |  |  |  | my $fund_source  = shift || 'balance'; | 
| 997 | 0 |  |  |  |  |  | my $assume_costs = shift; | 
| 998 |  |  |  |  |  |  |  | 
| 999 | 0 |  |  |  |  |  | my $params = { | 
| 1000 |  |  |  |  |  |  | 'pin' => $pin | 
| 1001 |  |  |  |  |  |  | }; | 
| 1002 |  |  |  |  |  |  |  | 
| 1003 | 0 | 0 |  |  |  |  | if (defined($amount)) { | 
| 1004 | 0 |  |  |  |  |  | $params->{'amount'} = $amount; | 
| 1005 |  |  |  |  |  |  | } | 
| 1006 |  |  |  |  |  |  |  | 
| 1007 | 0 | 0 |  |  |  |  | if (defined($notes)) { | 
| 1008 | 0 |  |  |  |  |  | $params->{'notes'} = $notes; | 
| 1009 |  |  |  |  |  |  | } | 
| 1010 |  |  |  |  |  |  |  | 
| 1011 | 0 | 0 |  |  |  |  | if (defined($fund_source)) { | 
| 1012 | 0 |  |  |  |  |  | $params->{'fundsSource'} = $fund_source; | 
| 1013 |  |  |  |  |  |  | } | 
| 1014 |  |  |  |  |  |  |  | 
| 1015 | 0 | 0 |  |  |  |  | if (!defined($assume_costs)) { | 
| 1016 | 0 |  |  |  |  |  | $assume_costs = 0; | 
| 1017 |  |  |  |  |  |  | } | 
| 1018 | 0 |  |  |  |  |  | $params->{'assumeCosts'} = $assume_costs; | 
| 1019 |  |  |  |  |  |  |  | 
| 1020 | 0 |  |  |  |  |  | my $response = $self->_post("requests/$id/fulfill",$params); | 
| 1021 |  |  |  |  |  |  |  | 
| 1022 | 0 |  |  |  |  |  | return $response; | 
| 1023 |  |  |  |  |  |  | } | 
| 1024 |  |  |  |  |  |  |  | 
| 1025 |  |  |  |  |  |  | # Function: cancel | 
| 1026 |  |  |  |  |  |  | # | 
| 1027 |  |  |  |  |  |  | # Cancels a pending mooney request. | 
| 1028 |  |  |  |  |  |  | # | 
| 1029 |  |  |  |  |  |  | # Parameters: | 
| 1030 |  |  |  |  |  |  | # | 
| 1031 |  |  |  |  |  |  | #   self - Object instance. | 
| 1032 |  |  |  |  |  |  | #   id   - Request Id. | 
| 1033 |  |  |  |  |  |  | # | 
| 1034 |  |  |  |  |  |  | # Returns: | 
| 1035 |  |  |  |  |  |  | #   Array of requests. | 
| 1036 |  |  |  |  |  |  | sub cancel_request | 
| 1037 |  |  |  |  |  |  | { | 
| 1038 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1039 | 0 |  | 0 |  |  |  | my $id   = shift || undef; | 
| 1040 |  |  |  |  |  |  |  | 
| 1041 | 0 | 0 |  |  |  |  | if (!defined($id)) { | 
| 1042 | 0 |  |  |  |  |  | $self->set_error('Must supply request id.'); | 
| 1043 | 0 |  |  |  |  |  | return 0; | 
| 1044 |  |  |  |  |  |  | } | 
| 1045 |  |  |  |  |  |  |  | 
| 1046 | 0 |  |  |  |  |  | my $response = $self->_post("requests/$id/cancel",{}); | 
| 1047 |  |  |  |  |  |  |  | 
| 1048 | 0 |  |  |  |  |  | return $response; | 
| 1049 |  |  |  |  |  |  | } | 
| 1050 |  |  |  |  |  |  |  | 
| 1051 |  |  |  |  |  |  | # Function: requests | 
| 1052 |  |  |  |  |  |  | # | 
| 1053 |  |  |  |  |  |  | # Get a list of pending money requests. | 
| 1054 |  |  |  |  |  |  | # | 
| 1055 |  |  |  |  |  |  | # Parameters: | 
| 1056 |  |  |  |  |  |  | # | 
| 1057 |  |  |  |  |  |  | #   self - Object instance. | 
| 1058 |  |  |  |  |  |  | # | 
| 1059 |  |  |  |  |  |  | # Returns: | 
| 1060 |  |  |  |  |  |  | #   Array of requests. | 
| 1061 |  |  |  |  |  |  | sub requests | 
| 1062 |  |  |  |  |  |  | { | 
| 1063 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1064 |  |  |  |  |  |  |  | 
| 1065 | 0 |  |  |  |  |  | my $response = $self->_get("requests"); | 
| 1066 |  |  |  |  |  |  |  | 
| 1067 | 0 |  |  |  |  |  | return $response; | 
| 1068 |  |  |  |  |  |  | } | 
| 1069 |  |  |  |  |  |  |  | 
| 1070 |  |  |  |  |  |  | # Function: transaction | 
| 1071 |  |  |  |  |  |  | # | 
| 1072 |  |  |  |  |  |  | # Grab information for the given transaction ID with | 
| 1073 |  |  |  |  |  |  | # app credentials (instead of oauth token) | 
| 1074 |  |  |  |  |  |  | # | 
| 1075 |  |  |  |  |  |  | # Parameters: | 
| 1076 |  |  |  |  |  |  | # | 
| 1077 |  |  |  |  |  |  | #   self        - Object instance. | 
| 1078 |  |  |  |  |  |  | #   transaction - Transaction ID. | 
| 1079 |  |  |  |  |  |  | # | 
| 1080 |  |  |  |  |  |  | # Returns: | 
| 1081 |  |  |  |  |  |  | #   Transaction information. | 
| 1082 |  |  |  |  |  |  | sub transaction | 
| 1083 |  |  |  |  |  |  | { | 
| 1084 | 0 |  |  | 0 | 0 |  | my $self        = shift; | 
| 1085 | 0 |  | 0 |  |  |  | my $transaction = shift || undef; | 
| 1086 |  |  |  |  |  |  |  | 
| 1087 | 0 | 0 |  |  |  |  | if (!defined($transaction)) { | 
| 1088 | 0 |  |  |  |  |  | $self->set_error('Must supply transaction id.'); | 
| 1089 | 0 |  |  |  |  |  | return 0; | 
| 1090 |  |  |  |  |  |  | } | 
| 1091 |  |  |  |  |  |  |  | 
| 1092 | 0 |  |  |  |  |  | my $params = { | 
| 1093 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 1094 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 1095 |  |  |  |  |  |  | }; | 
| 1096 |  |  |  |  |  |  |  | 
| 1097 | 0 |  |  |  |  |  | my $response = $self->_get("transactions/$transaction",$params); | 
| 1098 |  |  |  |  |  |  |  | 
| 1099 | 0 |  |  |  |  |  | return $response; | 
| 1100 |  |  |  |  |  |  | } | 
| 1101 |  |  |  |  |  |  |  | 
| 1102 |  |  |  |  |  |  | # Function: listings | 
| 1103 |  |  |  |  |  |  | # | 
| 1104 |  |  |  |  |  |  | # Retrieve a list of transactions for the user associated with the | 
| 1105 |  |  |  |  |  |  | # authorized access token. | 
| 1106 |  |  |  |  |  |  | # | 
| 1107 |  |  |  |  |  |  | # Parameters: | 
| 1108 |  |  |  |  |  |  | # | 
| 1109 |  |  |  |  |  |  | #   self    - Object instance. | 
| 1110 |  |  |  |  |  |  | #   since   - Earliest date and time for which to retrieve transactions. | 
| 1111 |  |  |  |  |  |  | #             Default: 7 days prior to current date / time in UTC. (DD-MM-YYYY) | 
| 1112 |  |  |  |  |  |  | #   types   - Types of transactions to retrieve. Options are money_sent, | 
| 1113 |  |  |  |  |  |  | #             money_received, deposit, withdrawal, and fee. | 
| 1114 |  |  |  |  |  |  | #   limit   - Number of transactions to retrieve between 1 and 200, Default: 10. | 
| 1115 |  |  |  |  |  |  | #   skip    - Number of transactions to skip. Default: 0. | 
| 1116 |  |  |  |  |  |  | #   groupid - ID specified by the client application. If specified, this call | 
| 1117 |  |  |  |  |  |  | #             will only return transactions with IDs matching the given groupId. | 
| 1118 |  |  |  |  |  |  | # | 
| 1119 |  |  |  |  |  |  | # Returns: | 
| 1120 |  |  |  |  |  |  | #   Array of transactions / false (0) on error. | 
| 1121 |  |  |  |  |  |  | sub listings | 
| 1122 |  |  |  |  |  |  | { | 
| 1123 | 0 |  | 0 | 0 | 0 |  | my $self    = shift || undef; | 
| 1124 | 0 |  | 0 |  |  |  | my $since   = shift || undef; | 
| 1125 | 0 |  | 0 |  |  |  | my $types   = shift || undef; | 
| 1126 | 0 |  | 0 |  |  |  | my $limit   = shift || 10; | 
| 1127 | 0 |  | 0 |  |  |  | my $skip    = shift || 0; | 
| 1128 | 0 |  | 0 |  |  |  | my $groupid = shift || undef; | 
| 1129 |  |  |  |  |  |  |  | 
| 1130 | 0 |  |  |  |  |  | my $params = { | 
| 1131 |  |  |  |  |  |  | 'client_id'     => $self->{'api_key'}, | 
| 1132 |  |  |  |  |  |  | 'client_secret' => $self->{'api_secret'}, | 
| 1133 |  |  |  |  |  |  | 'limit'         => $limit, | 
| 1134 |  |  |  |  |  |  | 'skip'          => $skip, | 
| 1135 |  |  |  |  |  |  | 'groupId'       => $groupid | 
| 1136 |  |  |  |  |  |  | }; | 
| 1137 |  |  |  |  |  |  |  | 
| 1138 | 0 | 0 |  |  |  |  | if (defined($since)) { | 
| 1139 | 0 | 0 |  |  |  |  | if ($since =~ /^\d{2}\-\d{2}\-\d{4}$/) { | 
| 1140 | 0 |  |  |  |  |  | $params->{'sinceDate'} = $since; | 
| 1141 |  |  |  |  |  |  | } else { | 
| 1142 | 0 |  |  |  |  |  | $self->set_error("Please supply a date in 'MM-DD-YYYY' format."); | 
| 1143 | 0 |  |  |  |  |  | return 0; | 
| 1144 |  |  |  |  |  |  | } | 
| 1145 |  |  |  |  |  |  | } | 
| 1146 |  |  |  |  |  |  |  | 
| 1147 | 0 | 0 |  |  |  |  | if (defined($types)) { | 
| 1148 | 0 |  |  |  |  |  | $params->{'types'} = join(',',@{$types}); | 
|  | 0 |  |  |  |  |  |  | 
| 1149 |  |  |  |  |  |  | } | 
| 1150 |  |  |  |  |  |  |  | 
| 1151 | 0 |  |  |  |  |  | my $response = $self->_get("transactions/",$params); | 
| 1152 |  |  |  |  |  |  |  | 
| 1153 | 0 |  |  |  |  |  | return $response; | 
| 1154 |  |  |  |  |  |  | } | 
| 1155 |  |  |  |  |  |  |  | 
| 1156 |  |  |  |  |  |  | # Function: stats | 
| 1157 |  |  |  |  |  |  | # | 
| 1158 |  |  |  |  |  |  | # Retrieve transactions stats for the user associated with the authorized | 
| 1159 |  |  |  |  |  |  | # access token. | 
| 1160 |  |  |  |  |  |  | # | 
| 1161 |  |  |  |  |  |  | # Parameters: | 
| 1162 |  |  |  |  |  |  | #   self       - Object instance. | 
| 1163 |  |  |  |  |  |  | #   types      - Options. Default: 'TransactionsCount', 'TransactionsTotal' | 
| 1164 |  |  |  |  |  |  | #   start_date - Search start date. Default: 0300 of the current day in UTC. | 
| 1165 |  |  |  |  |  |  | #   end_date   - Search end date. Default: 0300 of the current day in UTC. | 
| 1166 |  |  |  |  |  |  | # | 
| 1167 |  |  |  |  |  |  | # Returns: | 
| 1168 |  |  |  |  |  |  | #   void | 
| 1169 |  |  |  |  |  |  | sub stats | 
| 1170 |  |  |  |  |  |  | { | 
| 1171 | 0 |  |  | 0 | 0 |  | my $self       = shift; | 
| 1172 | 0 |  | 0 |  |  |  | my $types      = shift || ['TransactionsCount', 'TransactionsTotal']; | 
| 1173 | 0 |  | 0 |  |  |  | my $start_date = shift || undef; | 
| 1174 | 0 |  | 0 |  |  |  | my $end_date   = shift || undef; | 
| 1175 |  |  |  |  |  |  |  | 
| 1176 | 0 |  |  |  |  |  | my $params = { | 
| 1177 | 0 |  |  |  |  |  | 'types'     => join(',',@{$types}), | 
| 1178 |  |  |  |  |  |  | 'startDate' => $start_date, | 
| 1179 |  |  |  |  |  |  | 'endDate'   => $end_date | 
| 1180 |  |  |  |  |  |  | }; | 
| 1181 |  |  |  |  |  |  |  | 
| 1182 | 0 |  |  |  |  |  | my $response = $self->_get("transactions/stats",$params); | 
| 1183 |  |  |  |  |  |  |  | 
| 1184 | 0 |  |  |  |  |  | return $response; | 
| 1185 |  |  |  |  |  |  | } | 
| 1186 |  |  |  |  |  |  |  | 
| 1187 |  |  |  |  |  |  | # Function: start_gateway_session | 
| 1188 |  |  |  |  |  |  | # | 
| 1189 |  |  |  |  |  |  | # Starts a new gateway session. | 
| 1190 |  |  |  |  |  |  | # | 
| 1191 |  |  |  |  |  |  | # Parameters: | 
| 1192 |  |  |  |  |  |  | #   self - Object instance. | 
| 1193 |  |  |  |  |  |  | # | 
| 1194 |  |  |  |  |  |  | # Returns: | 
| 1195 |  |  |  |  |  |  | #   Void | 
| 1196 |  |  |  |  |  |  | sub start_gateway_session | 
| 1197 |  |  |  |  |  |  | { | 
| 1198 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1199 |  |  |  |  |  |  |  | 
| 1200 | 0 |  |  |  |  |  | $self->{'gateway_session'} = []; | 
| 1201 |  |  |  |  |  |  | } | 
| 1202 |  |  |  |  |  |  |  | 
| 1203 |  |  |  |  |  |  | # Function: add_gateway_product | 
| 1204 |  |  |  |  |  |  | # | 
| 1205 |  |  |  |  |  |  | # Adds a product to the gateway session. | 
| 1206 |  |  |  |  |  |  | # | 
| 1207 |  |  |  |  |  |  | # Parameters: | 
| 1208 |  |  |  |  |  |  | #   self        - Object instance. | 
| 1209 |  |  |  |  |  |  | #   name        - Product name. | 
| 1210 |  |  |  |  |  |  | #   price       - Product price. | 
| 1211 |  |  |  |  |  |  | #   quantity    - Product quantity. | 
| 1212 |  |  |  |  |  |  | #   description - Product description. | 
| 1213 |  |  |  |  |  |  | # | 
| 1214 |  |  |  |  |  |  | # Returns: | 
| 1215 |  |  |  |  |  |  | #   void | 
| 1216 |  |  |  |  |  |  | sub add_gateway_product | 
| 1217 |  |  |  |  |  |  | { | 
| 1218 | 0 |  |  | 0 | 0 |  | my $self        = shift; | 
| 1219 | 0 |  |  |  |  |  | my $name        = shift; | 
| 1220 | 0 |  |  |  |  |  | my $price       = shift; | 
| 1221 | 0 |  | 0 |  |  |  | my $quantity    = shift || undef; | 
| 1222 | 0 |  | 0 |  |  |  | my $description = shift || ''; | 
| 1223 |  |  |  |  |  |  |  | 
| 1224 | 0 | 0 |  |  |  |  | if (!defined($quantity)) { | 
| 1225 | 0 |  |  |  |  |  | $quantity = 1; | 
| 1226 |  |  |  |  |  |  | } | 
| 1227 |  |  |  |  |  |  |  | 
| 1228 | 0 |  |  |  |  |  | my $product = { | 
| 1229 |  |  |  |  |  |  | 'Name'        => $name, | 
| 1230 |  |  |  |  |  |  | 'Price'       => $price, | 
| 1231 |  |  |  |  |  |  | 'Description' => $description, | 
| 1232 |  |  |  |  |  |  | 'Quantity'    => $quantity | 
| 1233 |  |  |  |  |  |  | }; | 
| 1234 |  |  |  |  |  |  |  | 
| 1235 | 0 |  |  |  |  |  | push(@{$self->{'gateway_session'}},$product); | 
|  | 0 |  |  |  |  |  |  | 
| 1236 |  |  |  |  |  |  | } | 
| 1237 |  |  |  |  |  |  |  | 
| 1238 |  |  |  |  |  |  | # Function: get_gateway_url | 
| 1239 |  |  |  |  |  |  | # | 
| 1240 |  |  |  |  |  |  | # Creates and executes Server-to-Server checkout request. | 
| 1241 |  |  |  |  |  |  | # | 
| 1242 |  |  |  |  |  |  | # Parameters: | 
| 1243 |  |  |  |  |  |  | #   self                  - Object instance. | 
| 1244 |  |  |  |  |  |  | #   orderid               - Order Id. | 
| 1245 |  |  |  |  |  |  | #   discount              - Discount amount. | 
| 1246 |  |  |  |  |  |  | #   shipping              - Shipping amount. | 
| 1247 |  |  |  |  |  |  | #   tax                   - Tax ammount. | 
| 1248 |  |  |  |  |  |  | #   notes                 - Transaction notes. | 
| 1249 |  |  |  |  |  |  | #   callback              - Callback URL | 
| 1250 |  |  |  |  |  |  | #   allow_funding_sources - Allow funding sources? (1 - yes; 0 - no) | 
| 1251 |  |  |  |  |  |  | # | 
| 1252 |  |  |  |  |  |  | # Returns: | 
| 1253 |  |  |  |  |  |  | #   Gateway URL | 
| 1254 |  |  |  |  |  |  | sub get_gateway_url | 
| 1255 |  |  |  |  |  |  | { | 
| 1256 | 0 |  |  | 0 | 0 |  | my $self                  = shift; | 
| 1257 | 0 |  |  |  |  |  | my $destid                = shift; | 
| 1258 | 0 |  |  |  |  |  | my $orderid               = shift; | 
| 1259 | 0 |  | 0 |  |  |  | my $discount              = shift || 0; | 
| 1260 | 0 |  | 0 |  |  |  | my $shipping              = shift || 0; | 
| 1261 | 0 |  | 0 |  |  |  | my $tax                   = shift || 0; | 
| 1262 | 0 |  | 0 |  |  |  | my $notes                 = shift || ''; | 
| 1263 | 0 |  | 0 |  |  |  | my $callback              = shift || undef; | 
| 1264 | 0 |  |  |  |  |  | my $allow_funding_sources = shift; | 
| 1265 |  |  |  |  |  |  |  | 
| 1266 | 0 | 0 |  |  |  |  | if (!$self->is_id_valid($destid)) { | 
| 1267 | 0 |  |  |  |  |  | $self->set_error("Please supply a valid Dwolla Id."); | 
| 1268 | 0 |  |  |  |  |  | return 0; | 
| 1269 |  |  |  |  |  |  | } | 
| 1270 |  |  |  |  |  |  |  | 
| 1271 | 0 | 0 |  |  |  |  | if (!defined($allow_funding_sources)) { | 
| 1272 | 0 |  |  |  |  |  | $allow_funding_sources = 1; | 
| 1273 |  |  |  |  |  |  | } | 
| 1274 |  |  |  |  |  |  |  | 
| 1275 | 0 |  |  |  |  |  | my $subtotal = 0; | 
| 1276 |  |  |  |  |  |  |  | 
| 1277 | 0 |  |  |  |  |  | foreach my $product (@{$self->{'gateway_session'}}) { | 
|  | 0 |  |  |  |  |  |  | 
| 1278 | 0 |  |  |  |  |  | $subtotal += $product->{'Price'} * $product->{'Quantity'}; | 
| 1279 |  |  |  |  |  |  | } | 
| 1280 |  |  |  |  |  |  |  | 
| 1281 | 0 |  |  |  |  |  | my $total = sprintf("%.2f",($subtotal - abs($discount) + $shipping + $tax)); | 
| 1282 |  |  |  |  |  |  |  | 
| 1283 | 0 | 0 |  |  |  |  | my $request = { | 
|  |  | 0 |  |  |  |  |  | 
| 1284 |  |  |  |  |  |  | 'Key'                 => $self->{'api_key'}, | 
| 1285 |  |  |  |  |  |  | 'Secret'              => $self->{'api_secret'}, | 
| 1286 |  |  |  |  |  |  | 'Test'                => ($self->{'mode'} eq 'test') ? 1 : 0, | 
| 1287 |  |  |  |  |  |  | 'AllowFundingSources' => ($allow_funding_sources) ? 'true' : 'false', | 
| 1288 |  |  |  |  |  |  | 'PurchaseOrder'       => { | 
| 1289 |  |  |  |  |  |  | 'DestinationId'   => $destid, | 
| 1290 |  |  |  |  |  |  | 'OrderItems'      => $self->{'gateway_session'}, | 
| 1291 |  |  |  |  |  |  | 'Discount'        => (abs($discount) * -1), | 
| 1292 |  |  |  |  |  |  | 'Shipping'        => $shipping, | 
| 1293 |  |  |  |  |  |  | 'Tax'             => $tax, | 
| 1294 |  |  |  |  |  |  | 'Total'           => $total, | 
| 1295 |  |  |  |  |  |  | 'Notes'           => $notes, | 
| 1296 |  |  |  |  |  |  | } | 
| 1297 |  |  |  |  |  |  | }; | 
| 1298 |  |  |  |  |  |  |  | 
| 1299 | 0 | 0 |  |  |  |  | if (defined($self->{'redirect_uri'})) { | 
| 1300 | 0 |  |  |  |  |  | $request->{'Redirect'} = $self->{'redirect_uri'}; | 
| 1301 |  |  |  |  |  |  | } | 
| 1302 |  |  |  |  |  |  |  | 
| 1303 | 0 | 0 |  |  |  |  | if (defined($callback)) { | 
| 1304 | 0 |  |  |  |  |  | $request->{'Callback'} = $callback; | 
| 1305 |  |  |  |  |  |  | } | 
| 1306 |  |  |  |  |  |  |  | 
| 1307 | 0 | 0 |  |  |  |  | if (defined($orderid)) { | 
| 1308 | 0 |  |  |  |  |  | $request->{'OrderId'} = $orderid; | 
| 1309 |  |  |  |  |  |  | } | 
| 1310 |  |  |  |  |  |  |  | 
| 1311 | 0 |  |  |  |  |  | my $response = $self->_api_request(GATEWAY_URL,'POST',$request); | 
| 1312 |  |  |  |  |  |  |  | 
| 1313 | 0 | 0 |  |  |  |  | if ($response != 0) { | 
| 1314 | 0 | 0 |  |  |  |  | if ($response->{'Result'} ne 'Success') { | 
| 1315 | 0 |  |  |  |  |  | $self->set_error($response->{'Message'}); | 
| 1316 | 0 |  |  |  |  |  | return 0; | 
| 1317 |  |  |  |  |  |  | } | 
| 1318 |  |  |  |  |  |  | } else { | 
| 1319 | 0 |  |  |  |  |  | return $response; | 
| 1320 |  |  |  |  |  |  | } | 
| 1321 |  |  |  |  |  |  |  | 
| 1322 | 0 |  |  |  |  |  | return CHECKOUT_URL . '/' . $response->{'CheckoutId'}; | 
| 1323 |  |  |  |  |  |  | } | 
| 1324 |  |  |  |  |  |  |  | 
| 1325 |  |  |  |  |  |  | # Function: verify_gateway_signature | 
| 1326 |  |  |  |  |  |  | # | 
| 1327 |  |  |  |  |  |  | # Verify a signature that came back with an offsite gateway redirect. | 
| 1328 |  |  |  |  |  |  | # | 
| 1329 |  |  |  |  |  |  | # Parameters: | 
| 1330 |  |  |  |  |  |  | #   self        - Object instance. | 
| 1331 |  |  |  |  |  |  | #   signature   - HMAC signature. | 
| 1332 |  |  |  |  |  |  | #   checkout_id - Checkout Id. | 
| 1333 |  |  |  |  |  |  | #   amount      - Transaction amount. | 
| 1334 |  |  |  |  |  |  | # | 
| 1335 |  |  |  |  |  |  | # Returns: | 
| 1336 |  |  |  |  |  |  | #   1 - valid; 0 invalid | 
| 1337 |  |  |  |  |  |  | sub verify_gateway_signature | 
| 1338 |  |  |  |  |  |  | { | 
| 1339 | 0 |  |  | 0 | 0 |  | my $self        = shift; | 
| 1340 | 0 |  | 0 |  |  |  | my $signature   = shift || undef; | 
| 1341 | 0 |  | 0 |  |  |  | my $checkout_id = shift || undef; | 
| 1342 | 0 |  | 0 |  |  |  | my $amount      = shift || undef; | 
| 1343 |  |  |  |  |  |  |  | 
| 1344 | 0 |  |  |  |  |  | my $errors = 0; | 
| 1345 |  |  |  |  |  |  |  | 
| 1346 | 0 | 0 |  |  |  |  | if (!defined($signature)) { | 
| 1347 | 0 |  |  |  |  |  | $self->set_error("Please pass a proposed signature."); | 
| 1348 | 0 |  |  |  |  |  | $errors++; | 
| 1349 |  |  |  |  |  |  | } | 
| 1350 |  |  |  |  |  |  |  | 
| 1351 | 0 | 0 |  |  |  |  | if (!defined($checkout_id)) { | 
| 1352 | 0 |  |  |  |  |  | $self->set_error("Please pass a checkout id."); | 
| 1353 | 0 |  |  |  |  |  | $errors++; | 
| 1354 |  |  |  |  |  |  | } | 
| 1355 |  |  |  |  |  |  |  | 
| 1356 | 0 | 0 |  |  |  |  | if (!defined($amount)) { | 
| 1357 | 0 |  |  |  |  |  | $self->set_error("Please pass an amount."); | 
| 1358 | 0 |  |  |  |  |  | $errors++; | 
| 1359 |  |  |  |  |  |  | } | 
| 1360 |  |  |  |  |  |  |  | 
| 1361 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 1362 | 0 |  |  |  |  |  | return 0; | 
| 1363 |  |  |  |  |  |  | } | 
| 1364 |  |  |  |  |  |  |  | 
| 1365 | 0 |  |  |  |  |  | my $hmac = Digest::HMAC_SHA1->new($checkout_id . '&' . $amount,$self->{'api_secret'}); | 
| 1366 | 0 |  |  |  |  |  | my $hash = $hmac->hexdigest; | 
| 1367 |  |  |  |  |  |  |  | 
| 1368 | 0 | 0 |  |  |  |  | if ($hash ne $signature) { | 
| 1369 | 0 |  |  |  |  |  | $self->set_error('Dwolla signature verification failed.'); | 
| 1370 | 0 |  |  |  |  |  | return 0; | 
| 1371 |  |  |  |  |  |  | } | 
| 1372 |  |  |  |  |  |  |  | 
| 1373 | 0 |  |  |  |  |  | return 1; | 
| 1374 |  |  |  |  |  |  | } | 
| 1375 |  |  |  |  |  |  |  | 
| 1376 |  |  |  |  |  |  | # Function: verify_webhook_signature | 
| 1377 |  |  |  |  |  |  | # | 
| 1378 |  |  |  |  |  |  | # Verify the signature from Webhook notifications. | 
| 1379 |  |  |  |  |  |  | # | 
| 1380 |  |  |  |  |  |  | # Parameters: | 
| 1381 |  |  |  |  |  |  | #   self    - Object instance. | 
| 1382 |  |  |  |  |  |  | #   sheader - Signature header. | 
| 1383 |  |  |  |  |  |  | #   body    - Request body. | 
| 1384 |  |  |  |  |  |  | # | 
| 1385 |  |  |  |  |  |  | # Returns: | 
| 1386 |  |  |  |  |  |  | #   1 - valid; 0 - invalid; | 
| 1387 |  |  |  |  |  |  | sub verify_webhook_signature | 
| 1388 |  |  |  |  |  |  | { | 
| 1389 | 0 |  |  | 0 | 0 |  | my $self    = shift; | 
| 1390 | 0 |  |  |  |  |  | my $sheader = shift; | 
| 1391 | 0 |  |  |  |  |  | my $body    = shift; | 
| 1392 |  |  |  |  |  |  |  | 
| 1393 | 0 |  |  |  |  |  | my $hmac = Digest::HMAC_SHA1->new($body,$self->{'api_secret'}); | 
| 1394 | 0 |  |  |  |  |  | my $hash = $hmac->hexdigest; | 
| 1395 |  |  |  |  |  |  |  | 
| 1396 | 0 | 0 |  |  |  |  | if ($hash ne $sheader) { | 
| 1397 | 0 |  |  |  |  |  | $self->set_error('Dwolla signature verification failed.'); | 
| 1398 | 0 |  |  |  |  |  | return 0; | 
| 1399 |  |  |  |  |  |  | } | 
| 1400 |  |  |  |  |  |  |  | 
| 1401 | 0 |  |  |  |  |  | return 1; | 
| 1402 |  |  |  |  |  |  | } | 
| 1403 |  |  |  |  |  |  |  | 
| 1404 |  |  |  |  |  |  | # Function: masspay_create_job | 
| 1405 |  |  |  |  |  |  | # | 
| 1406 |  |  |  |  |  |  | # Send payments in bulk from the user with the given authorized access token. | 
| 1407 |  |  |  |  |  |  | # | 
| 1408 |  |  |  |  |  |  | # Parameters: | 
| 1409 |  |  |  |  |  |  | #   pin          - Dwolla pin number. | 
| 1410 |  |  |  |  |  |  | #   email        - Email address to send reports. | 
| 1411 |  |  |  |  |  |  | #   user_job_id  - A user assigned job ID for the MassPay job. | 
| 1412 |  |  |  |  |  |  | #   assume_costs - Should the sending user pay any associated fees? | 
| 1413 |  |  |  |  |  |  | #                  1 - Yes; 0 - No; | 
| 1414 |  |  |  |  |  |  | #   source       - Desired funding source from which to send money. | 
| 1415 |  |  |  |  |  |  | #                  Defaults to Dwolla 'balance'. | 
| 1416 |  |  |  |  |  |  | #   filedata     - The bulk payments data. Must be an array reference of | 
| 1417 |  |  |  |  |  |  | #                  anonymous hashes. | 
| 1418 |  |  |  |  |  |  | # | 
| 1419 |  |  |  |  |  |  | # Returns: | 
| 1420 |  |  |  |  |  |  | #   MassPay reeponse or false (0) on error. | 
| 1421 |  |  |  |  |  |  | sub masspay_create_job | 
| 1422 |  |  |  |  |  |  | { | 
| 1423 | 0 |  |  | 0 | 0 |  | my $self         = shift; | 
| 1424 | 0 |  |  |  |  |  | my $pin          = shift; | 
| 1425 | 0 |  |  |  |  |  | my $email        = shift; | 
| 1426 | 0 |  |  |  |  |  | my $user_job_id  = shift; | 
| 1427 | 0 |  |  |  |  |  | my $assume_costs = shift; | 
| 1428 | 0 |  | 0 |  |  |  | my $source       = shift || 'balance'; | 
| 1429 | 0 |  | 0 |  |  |  | my $filedata     = shift || undef; | 
| 1430 |  |  |  |  |  |  |  | 
| 1431 | 0 | 0 |  |  |  |  | my $test_string = ($self->{'mode'} eq 'test') ? 'true' : 'false'; | 
| 1432 |  |  |  |  |  |  |  | 
| 1433 | 0 |  |  |  |  |  | my $params = { | 
| 1434 |  |  |  |  |  |  | 'pin'         => $pin, | 
| 1435 |  |  |  |  |  |  | 'email'       => $email, | 
| 1436 |  |  |  |  |  |  | 'source'      => $source, | 
| 1437 |  |  |  |  |  |  | 'user_job_id' => $user_job_id, | 
| 1438 |  |  |  |  |  |  | 'test'        => $test_string, | 
| 1439 |  |  |  |  |  |  | 'filedata'    => $filedata, | 
| 1440 |  |  |  |  |  |  | 'assumeCosts' => $assume_costs, | 
| 1441 |  |  |  |  |  |  | 'token'       => $self->{'oauth_token'} | 
| 1442 |  |  |  |  |  |  | }; | 
| 1443 |  |  |  |  |  |  |  | 
| 1444 | 0 |  |  |  |  |  | my $response = $self->_parse_masspay( | 
| 1445 |  |  |  |  |  |  | $self->_api_request( | 
| 1446 |  |  |  |  |  |  | MASSPAY_URL . '/create', | 
| 1447 |  |  |  |  |  |  | 'POST', | 
| 1448 |  |  |  |  |  |  | $params | 
| 1449 |  |  |  |  |  |  | ) | 
| 1450 |  |  |  |  |  |  | ); | 
| 1451 |  |  |  |  |  |  |  | 
| 1452 | 0 |  |  |  |  |  | return $response; | 
| 1453 |  |  |  |  |  |  | } | 
| 1454 |  |  |  |  |  |  |  | 
| 1455 |  |  |  |  |  |  | # Function: masspay_job_details | 
| 1456 |  |  |  |  |  |  | # | 
| 1457 |  |  |  |  |  |  | # Parameters: | 
| 1458 |  |  |  |  |  |  | #   self        - Object instance. | 
| 1459 |  |  |  |  |  |  | #   uid         - Dwolla Id | 
| 1460 |  |  |  |  |  |  | #   job_id      - MassPay job id | 
| 1461 |  |  |  |  |  |  | #   user_job_id - User-assigned job id. | 
| 1462 |  |  |  |  |  |  | # | 
| 1463 |  |  |  |  |  |  | # Returns: | 
| 1464 |  |  |  |  |  |  | #   Job details or false (0) on set error. | 
| 1465 |  |  |  |  |  |  | sub masspay_job_details | 
| 1466 |  |  |  |  |  |  | { | 
| 1467 | 0 |  |  | 0 | 0 |  | my $self        = shift; | 
| 1468 | 0 |  |  |  |  |  | my $uid         = shift; | 
| 1469 | 0 |  |  |  |  |  | my $job_id      = shift; | 
| 1470 | 0 |  | 0 |  |  |  | my $user_job_id = shift || undef; | 
| 1471 |  |  |  |  |  |  |  | 
| 1472 | 0 |  |  |  |  |  | my $params = { | 
| 1473 |  |  |  |  |  |  | 'uid'         => $uid, | 
| 1474 |  |  |  |  |  |  | 'job_id'      => $job_id, | 
| 1475 |  |  |  |  |  |  | 'user_job_id' => $user_job_id | 
| 1476 |  |  |  |  |  |  | }; | 
| 1477 |  |  |  |  |  |  |  | 
| 1478 | 0 |  |  |  |  |  | my $response = $self->_parse_masspay( | 
| 1479 |  |  |  |  |  |  | $self->_api_request( | 
| 1480 |  |  |  |  |  |  | MASSPAY_URL . '/status', | 
| 1481 |  |  |  |  |  |  | 'POST', | 
| 1482 |  |  |  |  |  |  | $params | 
| 1483 |  |  |  |  |  |  | ) | 
| 1484 |  |  |  |  |  |  | ); | 
| 1485 |  |  |  |  |  |  |  | 
| 1486 | 0 |  |  |  |  |  | return $response; | 
| 1487 |  |  |  |  |  |  | } | 
| 1488 |  |  |  |  |  |  |  | 
| 1489 |  |  |  |  |  |  | # Function: is_id_valid | 
| 1490 |  |  |  |  |  |  | # | 
| 1491 |  |  |  |  |  |  | # Determines if provided Dwolla Id is valid. | 
| 1492 |  |  |  |  |  |  | # | 
| 1493 |  |  |  |  |  |  | # Parameters: | 
| 1494 |  |  |  |  |  |  | #   self - Object instance. | 
| 1495 |  |  |  |  |  |  | #   id   - Dwolla Id | 
| 1496 |  |  |  |  |  |  | # | 
| 1497 |  |  |  |  |  |  | # Returns: | 
| 1498 |  |  |  |  |  |  | #   1 for valid; 0 for invalid | 
| 1499 |  |  |  |  |  |  | sub is_id_valid | 
| 1500 |  |  |  |  |  |  | { | 
| 1501 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1502 | 0 |  |  |  |  |  | my $id   = shift; | 
| 1503 |  |  |  |  |  |  |  | 
| 1504 | 0 |  |  |  |  |  | my $valid = 0; | 
| 1505 |  |  |  |  |  |  |  | 
| 1506 | 0 | 0 | 0 |  |  |  | if (defined($id) && $id =~ /([0-9]{3})\-*([0-9]{3})\-*([0-9]{4})/) { | 
| 1507 | 0 |  |  |  |  |  | $valid = 1; | 
| 1508 |  |  |  |  |  |  | } | 
| 1509 |  |  |  |  |  |  |  | 
| 1510 | 0 |  |  |  |  |  | return $valid; | 
| 1511 |  |  |  |  |  |  | } | 
| 1512 |  |  |  |  |  |  |  | 
| 1513 |  |  |  |  |  |  | # Function: set_error | 
| 1514 |  |  |  |  |  |  | # | 
| 1515 |  |  |  |  |  |  | # Add error to error array. | 
| 1516 |  |  |  |  |  |  | # | 
| 1517 |  |  |  |  |  |  | # Parameters: | 
| 1518 |  |  |  |  |  |  | #   self  - Object instances. | 
| 1519 |  |  |  |  |  |  | #   error - Error string. | 
| 1520 |  |  |  |  |  |  | # | 
| 1521 |  |  |  |  |  |  | # Returns: | 
| 1522 |  |  |  |  |  |  | #   void | 
| 1523 |  |  |  |  |  |  | sub set_error | 
| 1524 |  |  |  |  |  |  | { | 
| 1525 | 0 |  |  | 0 | 0 |  | my $self  = shift; | 
| 1526 | 0 |  |  |  |  |  | my $error = shift; | 
| 1527 |  |  |  |  |  |  |  | 
| 1528 | 0 |  |  |  |  |  | push(@{$self->{'errors'}},$error); | 
|  | 0 |  |  |  |  |  |  | 
| 1529 |  |  |  |  |  |  | } | 
| 1530 |  |  |  |  |  |  |  | 
| 1531 |  |  |  |  |  |  | # Function: get_errors | 
| 1532 |  |  |  |  |  |  | # | 
| 1533 |  |  |  |  |  |  | # Returnserror array. | 
| 1534 |  |  |  |  |  |  | # | 
| 1535 |  |  |  |  |  |  | # Parameters: | 
| 1536 |  |  |  |  |  |  | #   self  - Object instances. | 
| 1537 |  |  |  |  |  |  | # | 
| 1538 |  |  |  |  |  |  | # Returns: | 
| 1539 |  |  |  |  |  |  | #   Error array | 
| 1540 |  |  |  |  |  |  | sub get_errors | 
| 1541 |  |  |  |  |  |  | { | 
| 1542 | 0 |  |  | 0 | 0 |  | my $self = shift; | 
| 1543 |  |  |  |  |  |  |  | 
| 1544 | 0 |  |  |  |  |  | my @err = (); | 
| 1545 | 0 |  |  |  |  |  | @err = @{$self->{'errors'}}; | 
|  | 0 |  |  |  |  |  |  | 
| 1546 |  |  |  |  |  |  |  | 
| 1547 | 0 |  |  |  |  |  | $self->{'errors'} = []; | 
| 1548 |  |  |  |  |  |  |  | 
| 1549 | 0 |  |  |  |  |  | return \@err; | 
| 1550 |  |  |  |  |  |  | } | 
| 1551 |  |  |  |  |  |  |  | 
| 1552 |  |  |  |  |  |  | # Function: set_debug_mode | 
| 1553 |  |  |  |  |  |  | # | 
| 1554 |  |  |  |  |  |  | # Toggle debug mode on / off. | 
| 1555 |  |  |  |  |  |  | # NOTE: Turning this on could potentially write sensitive information to | 
| 1556 |  |  |  |  |  |  | #       the screen / command-line. So, using this in production is not | 
| 1557 |  |  |  |  |  |  | #       advisable. | 
| 1558 |  |  |  |  |  |  | # | 
| 1559 |  |  |  |  |  |  | # Parameters: | 
| 1560 |  |  |  |  |  |  | #   self - Object instance. | 
| 1561 |  |  |  |  |  |  | #   mode - Debug mode. 1 = on; 0 = off | 
| 1562 |  |  |  |  |  |  | # | 
| 1563 |  |  |  |  |  |  | # Returns: | 
| 1564 |  |  |  |  |  |  | #   void | 
| 1565 |  |  |  |  |  |  | sub set_debug_mode | 
| 1566 |  |  |  |  |  |  | { | 
| 1567 | 0 |  |  | 0 | 0 |  | my $self       = shift; | 
| 1568 | 0 |  | 0 |  |  |  | my $debug_mode = shift || 0; | 
| 1569 |  |  |  |  |  |  |  | 
| 1570 | 0 |  |  |  |  |  | $self->{'debug_mode'} = $debug_mode; | 
| 1571 |  |  |  |  |  |  | } | 
| 1572 |  |  |  |  |  |  |  | 
| 1573 |  |  |  |  |  |  | # Function: _http_build_query | 
| 1574 |  |  |  |  |  |  | # | 
| 1575 |  |  |  |  |  |  | # Build HTTP query string similar to PHP's http_build_query() | 
| 1576 |  |  |  |  |  |  | # | 
| 1577 |  |  |  |  |  |  | # Parameters: | 
| 1578 |  |  |  |  |  |  | #   self   - Object instance. | 
| 1579 |  |  |  |  |  |  | #   params - Request query parameters. | 
| 1580 |  |  |  |  |  |  | # | 
| 1581 |  |  |  |  |  |  | # Returns: | 
| 1582 |  |  |  |  |  |  | #   Query string | 
| 1583 |  |  |  |  |  |  | sub _http_build_query | 
| 1584 |  |  |  |  |  |  | { | 
| 1585 | 0 |  |  | 0 |  |  | my $self   = shift; | 
| 1586 | 0 |  |  |  |  |  | my $params = shift; | 
| 1587 |  |  |  |  |  |  |  | 
| 1588 | 0 |  |  |  |  |  | my @tmp = (); | 
| 1589 | 0 |  |  |  |  |  | my $str; | 
| 1590 |  |  |  |  |  |  |  | 
| 1591 | 0 |  |  |  |  |  | foreach my $key (keys %{$params}) { | 
|  | 0 |  |  |  |  |  |  | 
| 1592 | 0 | 0 |  |  |  |  | if (defined($params->{$key})) { | 
| 1593 | 0 |  |  |  |  |  | $str = uri_escape($key) . '=' . uri_escape($params->{$key}); | 
| 1594 | 0 |  |  |  |  |  | push(@tmp,$str); | 
| 1595 |  |  |  |  |  |  | } | 
| 1596 |  |  |  |  |  |  | } | 
| 1597 |  |  |  |  |  |  |  | 
| 1598 | 0 |  |  |  |  |  | return join(q{&},@tmp); | 
| 1599 |  |  |  |  |  |  | } | 
| 1600 |  |  |  |  |  |  |  | 
| 1601 |  |  |  |  |  |  | # Function: _get | 
| 1602 |  |  |  |  |  |  | # | 
| 1603 |  |  |  |  |  |  | # Wrapper for _api_request (GET) | 
| 1604 |  |  |  |  |  |  | # | 
| 1605 |  |  |  |  |  |  | # Parameters: | 
| 1606 |  |  |  |  |  |  | #   self   - Object instance. | 
| 1607 |  |  |  |  |  |  | #   url    - Request URL. | 
| 1608 |  |  |  |  |  |  | #   params - Request query parameters. | 
| 1609 |  |  |  |  |  |  | # | 
| 1610 |  |  |  |  |  |  | # Returns: | 
| 1611 |  |  |  |  |  |  | #   JSON object or false (0) on failure | 
| 1612 |  |  |  |  |  |  | sub _get | 
| 1613 |  |  |  |  |  |  | { | 
| 1614 | 0 |  |  | 0 |  |  | my $self   = shift; | 
| 1615 | 0 |  |  |  |  |  | my $url    = shift; | 
| 1616 | 0 |  |  |  |  |  | my $params = shift; | 
| 1617 |  |  |  |  |  |  |  | 
| 1618 | 0 |  |  |  |  |  | $params->{'oauth_token'} = $self->{'oauth_token'}; | 
| 1619 |  |  |  |  |  |  |  | 
| 1620 | 0 |  |  |  |  |  | my $rurl = API_SERVER . '/' . $url . '?' . $self->_http_build_query($params); | 
| 1621 |  |  |  |  |  |  |  | 
| 1622 | 0 |  |  |  |  |  | my $response = $self->_parse($self->_api_request($rurl,'GET')); | 
| 1623 |  |  |  |  |  |  |  | 
| 1624 | 0 |  |  |  |  |  | return $response; | 
| 1625 |  |  |  |  |  |  | } | 
| 1626 |  |  |  |  |  |  |  | 
| 1627 |  |  |  |  |  |  | # Function: _post | 
| 1628 |  |  |  |  |  |  | # | 
| 1629 |  |  |  |  |  |  | # Wrapper for _api_request (POST) | 
| 1630 |  |  |  |  |  |  | # | 
| 1631 |  |  |  |  |  |  | # Parameters: | 
| 1632 |  |  |  |  |  |  | #   self          - Object instance. | 
| 1633 |  |  |  |  |  |  | #   url           - Request URL. | 
| 1634 |  |  |  |  |  |  | #   params        - Request query parameters. | 
| 1635 |  |  |  |  |  |  | #   include_token - Whether or not to include OAuth token. | 
| 1636 |  |  |  |  |  |  | # | 
| 1637 |  |  |  |  |  |  | # Returns: | 
| 1638 |  |  |  |  |  |  | #   JSON object or false (0) on failure | 
| 1639 |  |  |  |  |  |  | sub _post | 
| 1640 |  |  |  |  |  |  | { | 
| 1641 | 0 |  |  | 0 |  |  | my $self          = shift; | 
| 1642 | 0 |  |  |  |  |  | my $url           = shift; | 
| 1643 | 0 |  |  |  |  |  | my $params        = shift; | 
| 1644 | 0 |  |  |  |  |  | my $include_token = shift; | 
| 1645 |  |  |  |  |  |  |  | 
| 1646 | 0 |  |  |  |  |  | my $rurl = API_SERVER . '/' . $url; | 
| 1647 | 0 | 0 | 0 |  |  |  | if (!defined($include_token) || $include_token != 0) { | 
| 1648 | 0 |  |  |  |  |  | $rurl .= '?' . | 
| 1649 |  |  |  |  |  |  | $self->_http_build_query({ | 
| 1650 |  |  |  |  |  |  | 'oauth_token' => $self->{'oauth_token'} | 
| 1651 |  |  |  |  |  |  | }); | 
| 1652 |  |  |  |  |  |  | } | 
| 1653 |  |  |  |  |  |  |  | 
| 1654 | 0 |  |  |  |  |  | my $response = $self->_parse($self->_api_request($rurl,'POST',$params)); | 
| 1655 |  |  |  |  |  |  |  | 
| 1656 | 0 |  |  |  |  |  | return $response; | 
| 1657 |  |  |  |  |  |  | } | 
| 1658 |  |  |  |  |  |  |  | 
| 1659 |  |  |  |  |  |  | # Function: _api_request | 
| 1660 |  |  |  |  |  |  | # | 
| 1661 |  |  |  |  |  |  | # Make the API HTTP request. | 
| 1662 |  |  |  |  |  |  | # | 
| 1663 |  |  |  |  |  |  | # Parameters: | 
| 1664 |  |  |  |  |  |  | #   self   - Object instance. | 
| 1665 |  |  |  |  |  |  | #   url    - Request URL. | 
| 1666 |  |  |  |  |  |  | #   method - HTTP method. (GET,POST) | 
| 1667 |  |  |  |  |  |  | # | 
| 1668 |  |  |  |  |  |  | # Returns: | 
| 1669 |  |  |  |  |  |  | #   JSON object or false (0) on failure | 
| 1670 |  |  |  |  |  |  | sub _api_request | 
| 1671 |  |  |  |  |  |  | { | 
| 1672 | 0 |  |  | 0 |  |  | my $self    = shift; | 
| 1673 | 0 |  |  |  |  |  | my $url     = shift; | 
| 1674 | 0 |  |  |  |  |  | my $method  = shift; | 
| 1675 | 0 |  | 0 |  |  |  | my $params  = shift || undef; | 
| 1676 |  |  |  |  |  |  |  | 
| 1677 | 0 |  |  |  |  |  | my $content_type = 'application/json;charset=UTF-8'; | 
| 1678 |  |  |  |  |  |  |  | 
| 1679 | 0 |  |  |  |  |  | my $ua = LWP::UserAgent->new; | 
| 1680 | 0 |  |  |  |  |  | $ua->agent('Dwolla Perl API V' . $VERSION); | 
| 1681 |  |  |  |  |  |  |  | 
| 1682 | 0 | 0 |  |  |  |  | if ($self->{'debug_mode'}) { | 
| 1683 | 0 |  |  |  |  |  | print "Making '$method' request to '$url'\n"; | 
| 1684 |  |  |  |  |  |  | } | 
| 1685 |  |  |  |  |  |  |  | 
| 1686 | 0 |  |  |  |  |  | my $request; | 
| 1687 | 0 | 0 |  |  |  |  | if ($method eq 'GET') { | 
|  |  | 0 |  |  |  |  |  | 
| 1688 | 0 |  |  |  |  |  | $request = HTTP::Request->new(GET => $url); | 
| 1689 |  |  |  |  |  |  | } elsif ($method eq 'POST') { | 
| 1690 | 0 |  |  |  |  |  | my $data = JSON->new->utf8->encode($params); | 
| 1691 | 0 | 0 |  |  |  |  | if ($self->{'debug_mode'}) { | 
| 1692 | 0 |  |  |  |  |  | print "POST DATA: $data\n"; | 
| 1693 |  |  |  |  |  |  | } | 
| 1694 | 0 |  |  |  |  |  | $request = HTTP::Request->new(POST => $url); | 
| 1695 | 0 |  |  |  |  |  | $request->content_length(length($data)); | 
| 1696 | 0 |  |  |  |  |  | $request->content($data); | 
| 1697 |  |  |  |  |  |  | } | 
| 1698 |  |  |  |  |  |  |  | 
| 1699 | 0 |  |  |  |  |  | $request->content_type($content_type); | 
| 1700 |  |  |  |  |  |  |  | 
| 1701 | 0 |  |  |  |  |  | my $response = $ua->request($request); | 
| 1702 | 0 | 0 |  |  |  |  | if ($response->code() ne '200') { | 
| 1703 | 0 | 0 |  |  |  |  | if ($self->{'debug_mode'}) { | 
| 1704 | 1 |  |  | 1 |  | 2489 | use Data::Dumper; | 
|  | 1 |  |  |  |  | 11781 |  | 
|  | 1 |  |  |  |  | 190 |  | 
| 1705 | 0 |  |  |  |  |  | print Data::Dumper->Dump([$response],'response'); | 
| 1706 |  |  |  |  |  |  | } | 
| 1707 | 0 |  |  |  |  |  | $self->set_error("Request failed. HTTP status code: " . $response->code()); | 
| 1708 | 0 |  |  |  |  |  | return 0; | 
| 1709 |  |  |  |  |  |  | } | 
| 1710 |  |  |  |  |  |  |  | 
| 1711 | 0 |  |  |  |  |  | my $obj = JSON->new->utf8->decode($response->content); | 
| 1712 |  |  |  |  |  |  |  | 
| 1713 | 0 |  |  |  |  |  | return $obj; | 
| 1714 |  |  |  |  |  |  | } | 
| 1715 |  |  |  |  |  |  |  | 
| 1716 |  |  |  |  |  |  | # Function: _parse | 
| 1717 |  |  |  |  |  |  | # | 
| 1718 |  |  |  |  |  |  | # Parse the JSON response from API request for errors. | 
| 1719 |  |  |  |  |  |  | # | 
| 1720 |  |  |  |  |  |  | # Parameters: | 
| 1721 |  |  |  |  |  |  | #   self     - Object instance. | 
| 1722 |  |  |  |  |  |  | #   response - JSON response data. | 
| 1723 |  |  |  |  |  |  | # | 
| 1724 |  |  |  |  |  |  | # Returns: | 
| 1725 |  |  |  |  |  |  | #   JSON response or zero (0) on failure. | 
| 1726 |  |  |  |  |  |  | sub _parse | 
| 1727 |  |  |  |  |  |  | { | 
| 1728 | 0 |  |  | 0 |  |  | my $self     = shift; | 
| 1729 | 0 |  |  |  |  |  | my $response = shift; | 
| 1730 |  |  |  |  |  |  |  | 
| 1731 | 0 | 0 |  |  |  |  | if ($self->{'debug_mode'}) { | 
| 1732 | 1 |  |  | 1 |  | 8 | use Data::Dumper; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 198 |  | 
| 1733 | 0 |  |  |  |  |  | print Data::Dumper->Dump([$response],'response'); | 
| 1734 |  |  |  |  |  |  | } | 
| 1735 |  |  |  |  |  |  |  | 
| 1736 | 0 |  |  |  |  |  | my $errstring = ''; | 
| 1737 | 0 |  |  |  |  |  | my $errors    = 0; | 
| 1738 |  |  |  |  |  |  |  | 
| 1739 | 0 | 0 |  |  |  |  | if ($response->{'Success'} == 0) { | 
| 1740 | 0 |  |  |  |  |  | $errstring = $response->{'Message'}; | 
| 1741 | 0 |  |  |  |  |  | $errors++; | 
| 1742 |  |  |  |  |  |  |  | 
| 1743 | 0 | 0 |  |  |  |  | if ($response->{'Response'}) { | 
| 1744 | 0 |  |  |  |  |  | $errstring .= ' :: ' . join(',',@{$response->{'Response'}}); | 
|  | 0 |  |  |  |  |  |  | 
| 1745 |  |  |  |  |  |  | } | 
| 1746 |  |  |  |  |  |  | } | 
| 1747 |  |  |  |  |  |  |  | 
| 1748 | 0 | 0 |  |  |  |  | if ($errors) { | 
| 1749 | 0 |  |  |  |  |  | $self->set_error($errstring); | 
| 1750 | 0 |  |  |  |  |  | return 0; | 
| 1751 |  |  |  |  |  |  | } | 
| 1752 |  |  |  |  |  |  |  | 
| 1753 | 0 |  |  |  |  |  | return $response->{'Response'}; | 
| 1754 |  |  |  |  |  |  | } | 
| 1755 |  |  |  |  |  |  |  | 
| 1756 |  |  |  |  |  |  | # Function: _parse_masspay | 
| 1757 |  |  |  |  |  |  | # | 
| 1758 |  |  |  |  |  |  | # Parse the JSON response from MassPay API request for errors. | 
| 1759 |  |  |  |  |  |  | # | 
| 1760 |  |  |  |  |  |  | # Parameters: | 
| 1761 |  |  |  |  |  |  | #   self     - Object instance. | 
| 1762 |  |  |  |  |  |  | #   response - JSON response data. | 
| 1763 |  |  |  |  |  |  | # | 
| 1764 |  |  |  |  |  |  | # Returns: | 
| 1765 |  |  |  |  |  |  | #   JSON response or zero (0) on failure. | 
| 1766 |  |  |  |  |  |  | sub _parse_masspay | 
| 1767 |  |  |  |  |  |  | { | 
| 1768 | 0 |  |  | 0 |  |  | my $self     = shift; | 
| 1769 | 0 |  |  |  |  |  | my $response = shift; | 
| 1770 |  |  |  |  |  |  |  | 
| 1771 | 0 | 0 |  |  |  |  | if ($self->{'debug_mode'}) { | 
| 1772 | 1 |  |  | 1 |  | 6 | use Data::Dumper; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 115 |  | 
| 1773 | 0 |  |  |  |  |  | print Data::Dumper->Dump([$response],'response'); | 
| 1774 |  |  |  |  |  |  | } | 
| 1775 |  |  |  |  |  |  |  | 
| 1776 | 0 | 0 |  |  |  |  | if (!$response->{'success'}) { | 
| 1777 | 0 |  |  |  |  |  | $self->set_error($response->{'message'}); | 
| 1778 | 0 |  |  |  |  |  | return 0; | 
| 1779 |  |  |  |  |  |  | } | 
| 1780 |  |  |  |  |  |  |  | 
| 1781 | 0 |  |  |  |  |  | return $response->{'job'}; | 
| 1782 |  |  |  |  |  |  | } | 
| 1783 |  |  |  |  |  |  |  | 
| 1784 |  |  |  |  |  |  | 1; | 
| 1785 |  |  |  |  |  |  | __END__ |