Net-Braintree

 view release on metacpan or  search on metacpan

lib/Net/Braintree/Configuration.pm  view on Meta::CPAN

package Net::Braintree::Configuration;

use Net::Braintree::Gateway;
use Moose;

has merchant_id => (is => 'rw');
has partner_id => (is => 'rw');
has public_key  => (is => 'rw');
has private_key => (is => 'rw');
has gateway => (is  => 'ro', lazy => 1, default => sub { Net::Braintree::Gateway->new({config => shift})});

has environment => (
  is => 'rw',
  trigger => sub {
    my ($self, $new_value, $old_value) = @_;
    if ($new_value !~ /integration|development|sandbox|production|qa/) {
      warn "Assigned invalid value to Net::Braintree::Configuration::environment";
    }
    if ($new_value eq "integration") {
      $self->public_key("integration_public_key");
      $self->private_key("integration_private_key");
      $self->merchant_id("integration_merchant_id");
    }
  }
);

sub base_merchant_path {
  my $self = shift;
  return "/merchants/" . $self->merchant_id;
}

lib/Net/Braintree/HTTP.pm  view on Meta::CPAN

}

sub delete {
  my ($self, $path, $params) = @_;
  $self -> make_request($path, undef, 'DELETE');
}

sub make_request {
  my ($self, $path, $params, $verb) = @_;
  my $request = HTTP::Request->new($verb => $self->config->base_merchant_url . $path);
  $request->headers->authorization_basic($self->config->public_key, $self->config->private_key);

  if ($params) {
    $request->content(hash_to_xml($params));
    $request->content_type("text/xml; charset=utf-8");
  }

  $request->header("X-ApiVersion" => $self->config->api_version);
  $request->header("environment" => $self->config->environment);
  $request->header("User-Agent" => "Braintree Perl Module " . Net::Braintree->VERSION);

lib/Net/Braintree/TransparentRedirect/QueryString.pm  view on Meta::CPAN

  my ($self, $query_string) = @_;
  my $query = CGI->new($query_string);
  return $query->Vars;
}

sub hash_is_forged {
  my ($self, $query_string) = @_;
  if ($query_string =~ /(.*)(&|;)hash=(.*)/) {
    my $query_string_without_hash = $1;
    my $hash = $3;
    return $hash ne hexdigest($self->config->private_key, $query_string_without_hash);
  }
  return 1;
}

sub check_http_status {
  my($self, $query_string) = @_;
  my $params = $self->parse($query_string);
  confess "UnexpectedError: expected query string to have an http_status param" unless $params->{'http_status'};
  confess "AuthenticationError" if $params->{'http_status'} eq '401';
  confess "AuthorizationError"  if $params->{'http_status'} eq '403';

lib/Net/Braintree/TransparentRedirectGateway.pm  view on Meta::CPAN

  my ($self, $params) = @_;
  $params->{'api_version'} = $self->gateway->config->api_version;
  $params->{'time'}        = time_string;
  $params->{'public_key'}  = $self->gateway->config->public_key;
  return $self->build_tr_data($params);
}

sub build_tr_data {
  my ($self, $params) = @_;
  my $query = hash_to_query_string($params);
  my $tr_hash = hexdigest($self->gateway->config->private_key, $query);
  return "$tr_hash|$query";
}

sub _make_request {
  my($self, $path, $verb, $params) = @_;
  my $response = $self->gateway->http->$verb($path, $params);
  my $result = Net::Braintree::Result->new(response => $response);
  return $result;
}

lib/Net/Braintree/WebhookNotificationGateway.pm  view on Meta::CPAN


    if ($components[0] eq $self->gateway->config->public_key) {
      return $components[1];
    }
  }
}

sub _validate_signature {
  my ($self, $signature, $payload) = @_;
  my $matching_signature = $self->_matching_signature($signature, $payload);
  if (defined($matching_signature) && $matching_signature ne hexdigest($self->gateway->config->private_key, $payload)) {
    confess "InvalidSignature";
  }
}

sub verify {
  my ($self, $challenge) = @_;
  if ($challenge !~ /^[a-f0-9]{20,32}$/) {
    confess "InvalidChallenge";
  }
  return $self->gateway->config->public_key . "|" . hexdigest($self->gateway->config->private_key, $challenge);
}

1;

lib/Net/Braintree/WebhookTestingGateway.pm  view on Meta::CPAN

use Net::Braintree::WebhookNotification::Kind;
use Moose;

has 'gateway' => (is => 'ro');

sub sample_notification {
  my ($self, $kind, $id) = @_;

  my $sample_xml = $self->_sample_xml($kind, $id);
  my $payload = encode_base64($sample_xml);
  my $signature = $self->gateway->config->public_key . "|" . hexdigest($self->gateway->config->private_key, $payload);

  return ($signature, $payload);
}

sub _sample_xml {
  my ($self, $kind, $id) = @_;
  my $subject_sample_xml = $self->_subject_sample_xml($kind, $id);
  my $timestamp = strftime("%Y-%m-%dT%H:%M:%SZ", gmtime());

  return <<XML

lib/Net/Braintree/WebhookTestingGateway.pm  view on Meta::CPAN

      </discounts>
    </subscription>
XML
}

sub _partner_merchant_connected_sample_xml {
  return <<XML
        <partner-merchant>
          <merchant-public-id>public_id</merchant-public-id>
          <public-key>public_key</public-key>
          <private-key>private_key</private-key>
          <partner-merchant-id>abc123</partner-merchant-id>
          <client-side-encryption-key>cse_key</client-side-encryption-key>
        </partner-merchant>
XML
}

sub _partner_merchant_disconnected_sample_xml {
  return <<XML
        <partner-merchant>
          <partner-merchant-id>abc123</partner-merchant-id>

t/configuration.t  view on Meta::CPAN

use lib qw(lib test/lib);
use Net::Braintree;
use Test::More;
use Test::Warn;

$config = Net::Braintree->configuration;

$config->environment("sandbox");
$config->public_key("integration_public_key");
$config->merchant_id("integration_merchant_id");
$config->private_key("integration_private_key");

$config = Net::Braintree->configuration;

subtest "Configuration instance" => sub {
  is $config->environment, "sandbox", "Config environment";
  is $config->public_key , "integration_public_key", "Config public key";
  is $config->merchant_id, "integration_merchant_id", "Config merch id";
  is $config->private_key, "integration_private_key", "Config private key";
  is $config->base_merchant_path, "/merchants/integration_merchant_id", "generates base merchant path based on merchant id";
};

my @examples = (
  ['sandbox', "https://api.sandbox.braintreegateway.com:443/merchants/integration_merchant_id"],
  ['production', "https://api.braintreegateway.com:443/merchants/integration_merchant_id"],
  ['qa', "https://qa-master.braintreegateway.com:443/merchants/integration_merchant_id"]
);

foreach(@examples) {

t/configuration.t  view on Meta::CPAN


foreach(@examples) {
  my($environment, $url) = @$_;
  $config->environment($environment);
  is $config->auth_url, $url, "$environment auth_url";
}
subtest "setting configuration attributes with hash constructor" => sub {
  my $configuration = Net::Braintree::Configuration->new(
      merchant_id => "integration_merchant_id",
      public_key => "integration_public_key",
      private_key => "integration_private_key",
      environment => "development"
  );

  is $configuration->merchant_id, "integration_merchant_id";
  is $configuration->public_key, "integration_public_key";
  is $configuration->private_key, "integration_private_key";
  is $configuration->environment, "development";
};

warning_is {$config->environment("not_valid")} "Assigned invalid value to Net::Braintree::Configuration::environment",
  "Bad environment gives a warning";

$config->environment("integration");
$ENV{'GATEWAY_PORT'} = "8104";
is $config->port, "8104";
done_testing();

t/digest.t  view on Meta::CPAN

use lib qw(lib t/lib);
use Test::More;

my $query_string = "one=1&two=2&http_status=200";
my $private_key = "integration_private_key";
my $expected_hash = "3970ae558c51cf6f54340b5b1842d47ba1f5a19e";

use Net::Braintree::Digest qw(hexdigest hexdigest_256);
is(hexdigest($private_key, $query_string), $expected_hash, "Braintree digest works");

is(hexdigest_256("secret-key", "secret-message"),  "68e7f2ecab71db67b1aca2a638f5122810315c3013f27c2196cd53e88709eecc", "Braintree digest 256 works");

done_testing();

t/integration/configuration.t  view on Meta::CPAN

      number => "5431111111111111",
      expiration_date => "05/12"
  }});

  ok $result->is_success;
  is $result->transaction->amount, "10.00";

  my $config = Net::Braintree::Configuration->new;
  $config->environment("integration");
  $config->public_key("it_should_explode");
  $config->private_key("with_these_values");
  my $gateway = $config->gateway;

  should_throw("AuthenticationError", sub { $gateway->transaction->create({type => "sale", amount => "10.00"}) });
};

done_testing();

t/transparent_redirect_query_string.t  view on Meta::CPAN

use Net::Braintree::TestHelper;
use Net::Braintree::TransparentRedirect::QueryString;
use Net::Braintree::Digest qw(hexdigest);
use Net::Braintree::Configuration;

my $config = Net::Braintree::Configuration->new({environment => "integration"});

my $tr = Net::Braintree::TransparentRedirect::QueryString->new(config => $config);
my $query_string = "one=1&two=2&http_status=200";
my $cgi_query_string = "one=1;two=2;http_status=200";
my $hash = hexdigest($config->private_key, $query_string);
my $cgi_hash = hexdigest($config->private_key, $cgi_query_string);
my $complete_query_string = with_hash($query_string);
my $cgi_complete_query_string = "$cgi_query_string;hash=$cgi_hash";
my %query_as_hash = (one => 1, two => 2, http_status=>200, hash=>$hash);

subtest "check query string for forgery" => sub {
  ok($tr->validate($complete_query_string), "Query String is valid");
  should_throw("ForgedQueryString", sub {$tr->validate($query_string)}, "Query String is invalid without hash");
  should_throw("ForgedQueryString", sub {$tr->validate("$query_string&hash=wrong_hash")}, "Query string has wrong hash.");

  should_throw("UnexpectedError: expected query string to have an http_status param",

t/transparent_redirect_query_string.t  view on Meta::CPAN

  );

  foreach(@error_types) {
    my($error, $code) = @$_;
    should_throw($error, sub { $tr->validate(with_hash("http_status=$code")) }, "Raises $error if status is $code");
  }
};

sub with_hash {
  my $query_string = shift;
  my $hash = hexdigest($config->private_key, $query_string);
  return "$query_string&hash=$hash";
}

done_testing();

t/webhook_notification.t  view on Meta::CPAN

    Net::Braintree::WebhookNotification::Kind::PartnerMerchantConnected,
    "my_id"
  );

  my $webhook_notification = Net::Braintree::WebhookNotification->parse($signature, $payload);

  is $webhook_notification->kind, Net::Braintree::WebhookNotification::Kind::PartnerMerchantConnected;
  is $webhook_notification->partner_merchant->partner_merchant_id, "abc123";
  is $webhook_notification->partner_merchant->merchant_public_id, "public_id";
  is $webhook_notification->partner_merchant->public_key, "public_key";
  is $webhook_notification->partner_merchant->private_key, "private_key";
  is $webhook_notification->partner_merchant->client_side_encryption_key, "cse_key";
};

subtest 'sample_notification builds a sample notification for partner merchant disconnected', sub {
  my ($signature, $payload) = Net::Braintree::WebhookTesting->sample_notification(
    Net::Braintree::WebhookNotification::Kind::PartnerMerchantDisconnected,
    "my_id"
  );

  my $webhook_notification = Net::Braintree::WebhookNotification->parse($signature, $payload);



( run in 0.404 second using v1.01-cache-2.11-cpan-4d50c553e7e )