view release on metacpan or search on metacpan
WebService::Braintree::Configuration for details.
Class Style
use WebService::Braintree;
my $conf = WebService::Braintree->configuration;
$conf->environment( 'sandbox' );
$conf->merchant_id( 'use_your_merchant_id' );
$conf->public_key( 'use_your_public_key' );
$conf->private_key( 'use_your_private_key' );
my $result = WebService::Braintree::Transaction->sale(
...
);
Object Style
use WebService::Braintree;
my $gateway = WebService::Braintree::Gateway->new({
environment => 'sandbox',
merchant_id => 'use_your_merchant_id',
public_key => 'use_your_public_key',
private_key => 'use_your_private_key',
});
my $result = $gateway->transaction->sale(
...
);
Client Tokens
In general, your server code (that uses this library) will be
interacting with a client-side SDK (such as for Mobile or Javascript).
Create a sandbox_config.json
On the dashboard page of your new sandbox account, three are three
values you will need to put into a sandbox_config.json. The format
of the file must be:
{
"merchant_id": "<< value 1 >>",
"public_key": "<< value 2 >>",
"private_key": "<< value 3 >>"
}
replacing what's in the double-quotes with the appropriate values
from your Braintree sandbox's dashboard.
Link your Paypal Sandbox Account
You'll need to follow the instructions at
https://developers.braintreepayments.com/guides/paypal/testing-go-live/ruby#linked-paypal-testing.
This is required for some of the integration tests to pass.
L<WebService::Braintree::Configuration/> for details.
=head3 Class Style
use WebService::Braintree;
my $conf = WebService::Braintree->configuration;
$conf->environment( 'sandbox' );
$conf->merchant_id( 'use_your_merchant_id' );
$conf->public_key( 'use_your_public_key' );
$conf->private_key( 'use_your_private_key' );
my $result = WebService::Braintree::Transaction->sale(
...
);
=head3 Object Style
use WebService::Braintree;
my $gateway = WebService::Braintree::Gateway->new({
environment => 'sandbox',
merchant_id => 'use_your_merchant_id',
public_key => 'use_your_public_key',
private_key => 'use_your_private_key',
});
my $result = $gateway->transaction->sale(
...
);
=head3 Client Tokens
In general, your server code (that uses this library) will be interacting with
a client-side SDK (such as for Mobile or Javascript). That library will need a
=item Create a sandbox_config.json
On the dashboard page of your new sandbox account, three are three values you
will need to put into a C<< sandbox_config.json >>. The format of the file must
be:
{
"merchant_id": "<< value 1 >>",
"public_key": "<< value 2 >>",
"private_key": "<< value 3 >>"
}
replacing what's in the double-quotes with the appropriate values from your
Braintree sandbox's dashboard.
=item Link your Paypal Sandbox Account
You'll need to follow the instructions at L<< https://developers.braintreepayments.com/guides/paypal/testing-go-live/ruby#linked-paypal-testing >>. This is
required for some of the integration tests to pass.
lib/WebService/Braintree.pm view on Meta::CPAN
L<WebService::Braintree::Configuration/> for details.
=head3 Class Style
use WebService::Braintree;
my $conf = WebService::Braintree->configuration;
$conf->environment( 'sandbox' );
$conf->merchant_id( 'use_your_merchant_id' );
$conf->public_key( 'use_your_public_key' );
$conf->private_key( 'use_your_private_key' );
my $result = WebService::Braintree::Transaction->sale(
...
);
=head3 Object Style
use WebService::Braintree;
my $gateway = WebService::Braintree::Gateway->new({
environment => 'sandbox',
merchant_id => 'use_your_merchant_id',
public_key => 'use_your_public_key',
private_key => 'use_your_private_key',
});
my $result = $gateway->transaction->sale(
...
);
=head3 Client Tokens
In general, your server code (that uses this library) will be interacting with
a client-side SDK (such as for Mobile or Javascript). That library will need a
lib/WebService/Braintree.pm view on Meta::CPAN
=item Create a sandbox_config.json
On the dashboard page of your new sandbox account, three are three values you
will need to put into a C<< sandbox_config.json >>. The format of the file must
be:
{
"merchant_id": "<< value 1 >>",
"public_key": "<< value 2 >>",
"private_key": "<< value 3 >>"
}
replacing what's in the double-quotes with the appropriate values from your
Braintree sandbox's dashboard.
=item Link your Paypal Sandbox Account
You'll need to follow the instructions at L<< https://developers.braintreepayments.com/guides/paypal/testing-go-live/ruby#linked-paypal-testing >>. This is
required for some of the integration tests to pass.
lib/WebService/Braintree/Configuration.pm view on Meta::CPAN
has merchant_id => (is => 'rw');
=head2 public_key(?$value)
This is your public_key.
=cut
has public_key => (is => 'rw');
=head2 private_key(?$value)
This is your private_key.
=cut
has private_key => (is => 'rw');
=head2 environment(?$value)
This is your environment. The environment can be:
=over 4
=item development | integration
This is when you're using a local server for testing. It's unlikely you will
lib/WebService/Braintree/Configuration.pm view on Meta::CPAN
my ($self, $new_value, $old_value) = @_;
my %valid = map { $_ => 1 } qw(
development integration sandbox qa production
);
if (!$valid{$new_value}) {
warn 'Assigned invalid value to WebService::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');
}
}
);
has gateway => (is => 'ro', lazy => 1, default => sub {
WebService::Braintree::Gateway->new({config => shift});
});
# This method is used in ::HTTP
lib/WebService/Braintree/HTTP.pm view on Meta::CPAN
}
sub delete {
my $self = shift;
$self->make_request(DELETE => @_);
}
sub make_request {
my ($self, $verb, $path, $params, $file) = @_;
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 ($file) {
my $boundary = DateTime->now->strftime('%Q');
$request->content_type("multipart/form-data; boundary=${boundary}");
my @form_params = map {
$self->add_form_field($_, $params->{$_})
} keys %{$params // {}};
push @form_params, $self->add_file_part(file => $file);
lib/WebService/Braintree/TransparentRedirect/QueryString.pm view on Meta::CPAN
my $uri = URI->new;
$uri->query($query_string);
return { $uri->query_form};
}
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/WebService/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";
}
__PACKAGE__->meta->make_immutable;
1;
__END__
lib/WebService/Braintree/WebhookNotificationGateway.pm view on Meta::CPAN
# Definitively return undef if nothing is found.
return;
}
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";
}
return 1;
}
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);
}
__PACKAGE__->meta->make_immutable;
1;
__END__
lib/WebService/Braintree/WebhookTestingGateway.pm view on Meta::CPAN
use WebService::Braintree::WebhookNotification::Kind;
# This does not use Role::MakeRequest which provides the gateway attribute.
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/WebService/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/lib/WebService/Braintree/TestHelper.pm view on Meta::CPAN
$class->export_to_level(1, @EXPORT);
$config = WebService::Braintree->configuration;
$config->environment($env);
if ($env eq 'sandbox') {
my $conf_file = 'sandbox_config.json';
die "Can not run sandbox tests without $conf_file in distribution root" unless -e $conf_file;
my $sandbox = decode_json( do { local $/; open my($f), $conf_file; <$f>} );
$config->public_key($sandbox->{public_key});
$config->merchant_id($sandbox->{merchant_id});
$config->private_key($sandbox->{private_key});
}
}
}
# The sandbox must have specific items in it with specific values.
sub verify_sandbox {
subtest verify_sandbox => sub {
my %required_addons = (
increase_30 => superhashof(bless {
id => 'increase_30',
t/sandbox/README view on Meta::CPAN
In order to run these tests you need a file named 'sandbox_config.json' in the current directory.
The file is formatted thusly:
{
"public_key": "xxx",
"merchant_id": "xxx",
"private_key": "xxx"
}
Should you want to contribute to the development of Webservice::Braintree,
please mail zarquon@cpan.org for the shared credentials used by the
development team (however for casual development your own sandbox
credentials should mostly be fine).
You also need to have created elements in the control panel. These items are
verified by test preambles, but the description of how to create them is here.
t/sandbox/configuration.t view on Meta::CPAN
cmp_ok $result->transaction->amount, '==', $amount;
};
subtest "configuration two" => sub {
my $config = WebService::Braintree::Configuration->new;
$config->environment("sandbox");
$config->public_key("it_should_explode");
$config->merchant_id(WebService::Braintree::TestHelper->config->merchant_id);
$config->private_key("with_these_values");
my $gateway = $config->gateway;
should_throw("AuthenticationError", sub {
$gateway->transaction->create({
type => "sale",
amount => amount(5, 15),
});
});
};
t/unit/configuration.t view on Meta::CPAN
use lib qw(lib t/lib);
use WebService::Braintree;
my $config = WebService::Braintree->configuration;
$config->environment("sandbox");
$config->public_key("integration_public_key");
$config->merchant_id("integration_merchant_id");
$config->private_key("integration_private_key");
$config = WebService::Braintree->configuration;
subtest 'server()' => sub {
my %choices = (
development => 'localhost',
integration => 'localhost',
sandbox => 'api.sandbox.braintreegateway.com',
qa => 'qa-master.braintreegateway.com',
production => 'api.braintreegateway.com',
t/unit/digest.t view on Meta::CPAN
# vim: sw=4 ts=4 ft=perl
use 5.010_001;
use strictures 1;
use Test::More;
use lib qw(lib t/lib);
my $query_string = 'one=1&two=2&http_status=200';
my $private_key = 'integration_private_key';
my $expected_hash = '3970ae558c51cf6f54340b5b1842d47ba1f5a19e';
use WebService::Braintree::Digest qw(hexdigest);
is(
hexdigest($private_key, $query_string),
$expected_hash,
'Braintree digest works',
);
done_testing();
t/unit/transparent_redirect_query_string.t view on Meta::CPAN
use WebService::Braintree::TestHelper;
use WebService::Braintree::TransparentRedirect::QueryString;
use WebService::Braintree::Digest qw(hexdigest);
use WebService::Braintree::Configuration;
my $config = WebService::Braintree::Configuration->new({environment => 'integration'});
my $tr = WebService::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 {
t/unit/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/unit/webhook_notification.t view on Meta::CPAN
WebService::Braintree::WebhookNotification::Kind::PartnerMerchantConnected,
'my_id',
);
my $webhook_notification = WebService::Braintree::WebhookNotification->parse($signature, $payload);
is $webhook_notification->kind, WebService::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) = WebService::Braintree::WebhookTesting->sample_notification(
WebService::Braintree::WebhookNotification::Kind::PartnerMerchantDisconnected,
'my_id',
);
my $webhook_notification = WebService::Braintree::WebhookNotification->parse($signature, $payload);