NAME

Business::OnlinePayment::PayPal - PayPal backend for Business::OnlinePayment

SYNOPSIS

  use Business::OnlinePayment;
  
  my $tx = Business::OnlinePayment->new(
      "PayPal",
      "Username"  => "my_api1.domain.tld",
      "Password"  => "Xdkis9k3jDFk39fj29sD9",    ## supplied by PayPal
      "Signature" => "f7d03YCpEjIF3s9Dk23F2...", ## supplied by PayPal
  );
  
  $tx->content(
      action      => "Normal Authorization",
      amount      => "19.95",
      type        => "Visa",
      card_number => "4111111111111111",
      expiration  => "01/10",
      cvv2        => "123",
      name        => "John Doe",
      address     => "123 My Street",
      city        => "Chicago",
      state       => "IL",
      zip         => "61443",
      IPAddress   => "10.0.0.1",
  );
  
  $tx->test_transaction(1);
  $tx->submit;
  
  if ( $tx->is_success ) {
      print(
          "SUCCESS:\n",
          "  CorrelationID: ", $tx->correlationid, "\n",
          "  auth:          ", $tx->authorization, "\n",
          "  AVS code:      ", $tx->avs_code, "\n",
          "  CVV2 code:     ", $tx->cvv2_code, "\n",
      );
  }
  else {
      print(
          "ERROR: ", $tx->error_message, "\n"
      );
  }

DESCRIPTION

Business::OnlinePayment::PayPal is a plugin for using PayPal as a payment processor backend with the Business::OnlinePayment API. Specifically, this module uses PayPal's 'DoDirectPayment' operation which utilizes the 'DoDirectPaymentRequest' message type.

This module does not do any checks to be sure that all the required fields/arguments/attributes/values, per PayPal's WSDL/XSD, have been provided. In general, PayPal's service will catch errors and return relevant information. However when requests do not meet the minimum message format/structure requirements or if the request contains information not supported by the 'DoDirectPaymentRequest' very generic errors (i.e. PPBaseException) may be sent to STDERR by underlying modules and our response data structure may be completely empty.

Anyone using this module or any modules that talk to PayPal should familiarize themselves with the information available at PayPal's integration center. See the "SEE ALSO" section for links to useful reference material.

METHODS

The following methods exist for use with this module.

Convenience methods

authorization()

Provides access to the TransactionID returned in the PayPal results. This method is part of the Business::OnlinePayment "standard" API.

transactionid()

This method is an alias for the "authorization()" method.

correlationid()

Provides access to the CorrelationID returned in the PayPal results.

order_number()

This method is an alias for the "correlationid()" method. It is provided for compatibility with the PayflowPro backend.

server_response()

Provides access, via a hashref, to the results hash returned in the Business::PayPal::API results object returned by DoDirectPaymentRequest. This method is part of the Business::OnlinePayment "standard" API.

result_code()

Returns "" or the first ErrorCode returned from DoDirectPaymentRequest. This method is part of the Business::OnlinePayment "standard" API.

avs_code()

Returns the AVSCode returned from DoDirectPaymentRequest.

cvv2_code()

Returns the CVV2Code returned from DoDirectPaymentRequest.

is_success()

Returns 1 or 0 on success or failure of DoDirectPaymentRequest. This method is part of the Business::OnlinePayment "standard" API.

error_message()

Returns a string containing an error message, if any. This method is part of the Business::OnlinePayment "standard" API.

set_defaults()

Creates accessor methods "avs_code()", "correlationid()", "cvv2_code()" and __map_fields_data (see "get_request_data").

get_credentials()

Get the credential information for Business::PayPal::API that was provided to Business::OnlinePayment::new(). The supported arguments are:

  • Username Password PKCS12File PKCS12Password

  • Username Password CertFile KeyFile

  • Username Password Signature

Business::OnlinePayment::PayPal does not currently map arguments to new() from (standard?) names to the PayPal backend specific name. For example, if the argument "login" were passed to new() the module could potentially try to identify that and map that to "Username".

NOTE: This requirement/capability seems to be more of a Business::OnlinePayment issue than a backend issue and it isn't clear if behavior like this is needed in this module so I will wait for user feedback to determine if we need/want to implement this.

get_request_data()

Return a hash %data with all the data from content() that we will try to use in our request to PayPal. Tasks performed:

  • Remove unsupported values from our hash (i.e. description fax login password phone).

  • Translate the value in "action" if necessary, from Business::OnlinePayment names to names used by PayPal. Translations used are:

        "normal authorization" => "Sale"
        "authorization only"   => "Authorization"
        "void"                 => "None"
  • Translate the value in "type" if necessary, from Business::OnlinePayment names to names used by PayPal. See "normalize_creditcardtype()" for details.

  • If necessary, separate ExpMonth and ExpYear values from the single "standard" Business::OnlinePayment "expiration" field. See "parse_expiration()" for details.

  • Call get_remap_fields to map content() into the %data that we will pass to PayPal. All fields not "mapped" will be passed AS-IS. The mapping used is (map hashref stored in __map_fields_data()):

      PaymentAction    => "action"
      # Payment Detail
      OrderTotal       => "amount"
      # Credit Card
      CreditCardType   => "type"
      CreditCardNumber => "card_number"
      CVV2             => undef
      # Card Owner / Payer Name
      Payer            => "email"
      FirstName        => "name"
      LastName         => undef
      # Payer Address
      Street1          => "address"
      Street2          => undef
      CityName         => "city"
      StateOrProvince  => "state"
      Country          => "country"
      PostalCode       => "zip"

    NOTE: an 'undef' on the right hand side means that field will be looked for as the mixed-case name specified on the left and also as an all lower-case name).

submit()

Method that overrides the superclass stub. This method performs the following tasks:

  • Get credentials to be used for authentication with PayPal by calling "get_credentials()".

  • Get request data to be passed to PayPal by calling "get_request_data()".

  • Connect to PayPal and perform a DirectPaymentRequest. The request will be run in test mode (i.e. go to PayPal's "sandbox") if test_transaction() returns true. NOTE: I believe PayPal automatically does AVS checking if possible.

  • Store the entire response in server_response().

  • Set result_code() to "" or the first ErrorCode in Errors (if present).

  • Set avs_code() to the response AVSCode.

  • Set cvv2_code() to the response CVV2Code.

  • Set is_success() to 1 or 0, indicating if the transaction was successful or not.

  • On success, set authorization() with the value of TransactionID. On failure, set error_message() with a string containing all ErrorCode and LongMessage values joined together.

get_remap_fields()

  Options:
    content => $href (default: { $self->content } )
    map     => $href (default: { } )

Combines some of the functionality of get_fields and remap_fields for convenience and also extends/alters their behavior. Unlike Business::OnlinePayment::remap_fields, this doesn't modify content(), and can therefore be called more than once. Also, unlike Business::OnlinePayment::get_fields in 3.x, this doesn't exclude fields content with a value of undef.

normalize_creditcardtype()

Attempt to normalize the credit card type to names supported by PayPal. If the module is unable to identify the given type it leaves the value AS-IS and leaves it to PayPal to do what it can with the data given. Supported card types are:

  Visa | MasterCard | Discover | Amex

Translations used are:

  /^vis/i     => "Visa"
  /^mas/i     => "MasterCard"
  /^ame/i     => "Amex"
  /^dis/i     => "Discover"

parse_expiration()

Business::OnlinePayment documents the use of a single expiration or exp_date value. However PayPal requires separate values for both the month and year. There are multiple formates that expiration dates are often specified in so, we try to our best to handle them all.

The following formats are supported:

  YYYY[.-]MM, YYYY[.-]M, YY[-/]M, YY[.-]MM
  MM[-/]YYYY, M[-/]YYYY, M[-/]YY, MM/YY, MMYY

NOTE: this method is based on the parse_exp method found in Business::OnlinePayment::InternetSecure.

If an unrecognized format is encountered this method it will return an empty list and leave it to PayPal to do what it can with the data given. To avoid having this module attempt to parse 'expiration' explicitly set ExpMonth and ExpYear in content().

SEE ALSO

http://sourceforge.net/projects/bop-paypal/: source code for this module is maintained on Sourceforge.

Business::OnlinePayment: the framework/API used by this module.

Business::PayPal::API: details and code that this module relies on to actually do the work of talking to PayPal servers.

Business::OnlinePayment::InternetSecure: the module that helped to guide me in development of this module.

https://www.paypal.com/integration: PayPal's integration center home and the source of all information relating to how to integrate to services provided by PayPal.

AUTHOR

Phil Lobbes <phil at perkpartners dot com>

COPYRIGHT

Copyright (C) 2006 by Phil Lobbes

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.