Skip to content

Commit

Permalink
Support Transfer Reversals (#20)
Browse files Browse the repository at this point in the history
Adds support for reversing existing transfers via a new create_reversal method. This method accepts three arguments:

- (Required) The transfer ID - any stringifiable value
- (Optional) Reversal data - a hashref defaulting to {}
- (Optional) Options - a hashref defaulting to {}. Right now the only valid key is 'headers', which is passed verbatim to the LWP::UserAgent as request headers.

The method signature ($id, $data = {}, $opts = {}) is meant as a template for all methods that act on a single, existing object. Right now, WS::Stripe uses a mix of positional and named parameters that is not consistent and requires looking back at the documentation. We should unify these signatures to promote understanding. For operations involving new objects, I'd propose the very-similar signature ($data, $opts = {}).
  • Loading branch information
danschmidt5189 committed Jul 13, 2015
1 parent 9d0a6bf commit ecf3eec
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Makefile.PL
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.037.
# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.036.
use strict;
use warnings;

Expand Down Expand Up @@ -36,7 +36,7 @@ my %WriteMakefileArgs = (
"strict" => 0,
"warnings" => 0
},
"VERSION" => "0.1100",
"VERSION" => "0.1200",
"test" => {
"TESTS" => "t/*.t"
}
Expand Down
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ WebService::Stripe - Stripe API bindings

# VERSION

version 0.1100
version 0.1200

# SYNOPSIS

Expand Down Expand Up @@ -243,6 +243,26 @@ Example:

cancel_transfer($id)

## create\_reversal

Reverses an existing transfer.

Example:

$ws_stripe->create_reversal(
# Transfer ID (required)
$xfer_id,
{ # POST data (optional)
refund_application_fee => 'true'
},
{ # Request options (optional)
stripe_account => $account->{'id'},
headers => {
'Other-Header' => 'Foo'
}
}
);

## get\_balance

get_balance()
Expand Down
2 changes: 1 addition & 1 deletion dist.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ license = Perl_5
copyright_holder = Tilt, Inc
copyright_year = 2014

version = 0.1100
version = 0.1200

[@Filter]
-bundle = @Basic
Expand Down
34 changes: 34 additions & 0 deletions lib/WebService/Stripe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ method cancel_transfer(Str $id, :$headers) {
return $self->post("/v1/transfers/$id/cancel", undef, headers => $headers);
}

method create_reversal($xfer_id, HashRef $data = {}, HashRef $opts = {}) {
return $self->post("/v1/transfers/$xfer_id/reversals", $data,
headers => $self->_stripe_opts_to_headers($opts),
);
}

method get_bitcoin_receivers(HashRef :$query, :$headers) {
return $self->get( "/v1/bitcoin/receivers", $query, headers => $headers );
}
Expand All @@ -185,6 +191,14 @@ method get_bitcoin_receiver(Str $id, :$headers) {
return $self->get( "/v1/bitcoin/receivers/$id", {}, headers => $headers );
}

method _stripe_opts_to_headers(HashRef $opts) {
my $headers = $opts->{'headers'} // {};
if ($opts->{'stripe_account'}) {
$headers->{'Stripe-Account'} = $opts->{'stripe_account'};
}
return $headers;
}

# ABSTRACT: Stripe API bindings

=head1 SYNOPSIS
Expand Down Expand Up @@ -428,6 +442,26 @@ Example:
cancel_transfer($id)
=head2 create_reversal
Reverses an existing transfer.
Example:
$ws_stripe->create_reversal(
# Transfer ID (required)
$xfer_id,
{ # POST data (optional)
refund_application_fee => 'true'
},
{ # Request options (optional)
stripe_account => $account->{'id'},
headers => {
'Other-Header' => 'Foo'
}
}
);
=head2 get_balance
get_balance()
Expand Down
80 changes: 69 additions & 11 deletions t/04-transfers.t
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use Test::Modern;
use Test::Modern qw(:deeper :fatal :more);
use t::lib::Common qw(:constants skip_unless_has_secret stripe);
use JSON qw(from_json);

Expand All @@ -17,39 +17,97 @@ my $bank = stripe->add_bank(
},
account_id => $account->{id},
);
cmp_deeply $bank => TD->superhashof({ last4 => 6789 }), 'created bank';
cmp_deeply $bank => superhashof({ last4 => 6789 }), 'created bank';

subtest 'create a transfer and do stuff with it' => sub {
my $transfer = stripe->create_transfer({
amount => 100,
currency => 'cad',
destination => $account->{id},
});
cmp_deeply $transfer => TD->superhashof({
id => TD->re('^tr_'),
cmp_deeply $transfer => superhashof({
id => re('^tr_'),
amount => 100,
});
my $transfer_id = $transfer->{id};
}),
'... Created a transfer';

my $transfer_id = $transfer->{id};
$transfer = stripe->update_transfer($transfer->{id}, data => {
'metadata[foo]' => 'bar'
});
is $transfer->{id} => $transfer_id;
is $transfer->{id}, $transfer_id,
'... Updated a transfer';

$transfer = stripe->get_transfer($transfer->{id});
cmp_deeply $transfer => TD->superhashof({
cmp_deeply $transfer => superhashof({
id => $transfer_id,
amount => 100,
metadata => { foo => 'bar' },
});
}),
'... Got an existing transfer';

my $exc = exception { stripe->cancel_transfer($transfer->{id}) };
is $exc->code => 400;
# Expect failure b/c Stripe's test env doesn't support this
my $err = exception { stripe->cancel_transfer($transfer->{id}) };
like $err, qr/while they are pending/,
'... Sent cancel request to Stripe';
};

subtest 'list transfers' => sub {
my $transfers = stripe->get_transfers;
ok $transfers->{data}[0]{amount};
};

subtest 'create_reversal' => sub {
subtest "Can create a complete reversal" => sub {
my $xfer = stripe->create_transfer({
amount => 100,
currency => 'cad',
destination => $account->{'id'},
'metadata[tester]' => 'WebService::Stripe::create_reversal',
});

my $reversal = stripe->create_reversal($xfer->{'id'});
cmp_deeply $reversal, superhashof({
object => 'transfer_reversal',
amount => 100,
}),
'... Created a full reversal',
or diag explain $reversal;
};

subtest "Can create a partial reversal" => sub {
my $xfer = stripe->create_transfer({
amount => 50,
currency => 'cad',
destination => $account->{'id'},
});

my $reversal = stripe->create_reversal($xfer->{'id'});
cmp_deeply $reversal, superhashof({
object => 'transfer_reversal',
amount => 50,
}),
'... Created a 50% reversal',
or diag explain $reversal;
};

subtest "Can reverse an Account-scoped bank transfer" => sub {
my $xfer = stripe->create_transfer({
amount => 50,
currency => 'cad',
destination => $bank->{'id'},
}, headers => { stripe_account => $account->{'id'} });

my $err = exception {
stripe->create_reversal($xfer->{'id'}, {
amount => 25,
}, { stripe_account => $account->{'id'} });
};

# Expect failure b/c Stripe's test environment doesn't support this
like $err, qr/while they are pending/,
'... Sent reversal request to Stripe';
};
};

done_testing;

0 comments on commit ecf3eec

Please sign in to comment.